Generics 为什么可以';t我用let 3;:Arc<;创建一个trait对象;动态特性>;=value.into()? impl From for Arc{ fn从(t:t)->弧 }

Generics 为什么可以';t我用let 3;:Arc<;创建一个trait对象;动态特性>;=value.into()? impl From for Arc{ fn从(t:t)->弧 },generics,rust,traits,trait-objects,Generics,Rust,Traits,Trait Objects,对于所有通用防锈代码,在任何T上都有一个隐式大小的。这: fn函数(t:&t){ 实际上是这样的: fn函数(t:&t){ 这可能并不总是你想要的,所以这是你必须明确选择不喜欢的唯一特征: fn函数(t:&t){ 因此,在你的情况下: impl From for Arc{ fn从(t:t)->弧 } 实际上是: impl From for Arc{ fn从(t:t)->弧 } 这就是为什么你不能一些值.into()一个弧,因为所有的特征对象都没有大小 首先,我们可以通过查看中的定义来确

对于所有通用防锈代码,在任何
T
上都有一个隐式
大小的
。这:

fn函数(t:&t){
实际上是这样的:

fn函数(t:&t){
这可能并不总是你想要的,所以这是你必须明确选择不喜欢的唯一特征:

fn函数(t:&t){
因此,在你的情况下:

impl From for Arc{
fn从(t:t)->弧
}
实际上是:

impl From for Arc{
fn从(t:t)->弧
}
这就是为什么你不能
一些值.into()
一个
,因为所有的特征对象都没有大小

首先,我们可以通过查看
中的
定义来确定为什么存在这种限制:

pub trait Into<T> {
    fn into(self) -> T;
}
pub trait From{
fn来自(T)->Self;
}
from(T)
意味着它必须获取一些
T
并将其放入函数的调用堆栈中,这意味着
T
必须在编译时具有已知的大小,因此必须是
大小的

更新

因此,这也适用于
Arc::new(T)
,因为该函数是在impl块中定义的,如下所示:

impl<T> From<T> for Arc<T> {
    fn from(t: T) -> Arc<T>
}
在本例中,在触发未调整大小的强制之前,请明确您要从一个调整大小的类型转换为另一个调整大小的类型,即
TraitImpl
Arc

以下是其他变体:

使用std::sync::Arc;
性状{}
结构TraitImpl{}
TraitImpl{}的impl特征
fn main(){
let value=TraitImpl{};
让3;:Arc=Arc::new(value);//编译
let value=TraitImpl{};
让3;:Arc=::from(value);//编译
let value=TraitImpl{};
让3;:Arc=Arc::from(value);//编译,可以在这里推断弧
let value=TraitImpl{};
让u3;:Arc=Into:::Into(value);//编译
let value=TraitImpl{};
让∶Arc=Into:::Into(value);//编译,可以在这里推断弧
let value=TraitImpl{};
让3;:Arc=Into::Into(value);//不编译,在这里推断Arc
}

您的两行代码有一个根本的区别。第一个:

impl<T> for Arc<T> {
    fn new(T) -> Arc<T> {
        ...
    }
}
因此,类型
T
是从
value
的类型(即
TraitImpl
)推导出来的,并且创建了一个
Arc
。 然后,该类型隐式地指向
,并且所有编译都很好


但第二行是骗子:

impl<T> Arc<T> {
    pub fn new(data: T) -> Arc<T>
}
现在编译器想知道
T
是什么类型。因为它是函数的返回,所以它猜测
T
Arc
。现在,
的唯一有趣的实现是来自

pub trait Into<T> {
    fn into(self) -> T;
}
然后,编译器显示一些失败的候选项并发出错误



TL;博士实际上,您需要执行两个转换:从
TraitImpl
Arc
,然后从
Arc
Arc
。但是你不能在一个协同工作中同时完成这两项工作,编译器必须以某种方式指定中间类型。

这不应该也适用于
impl-Arc
吗?@JohnKugelman它不适用于Arc,我已经更新了我的答案来解释原因,但这里还有一个链接,可以让你自己看看<代码>结构弧
具有
T:?大小
,但
impl
块没有。这是否意味着
impl
impl
?@JohnKugelman是对的,
fn new
是在
impl Arc
块中定义的,没有
大小的
绑定。它工作的原因是因为
Arc::new(value)
返回一个
Arc
,可以强制为
Arc
value.into()
使用类型推断来确定
必须返回的内容。into()
必须返回并被混淆,因为没有
impl-From for-Arc
Arc::From(value)
也不能使用显式
TraitImpl
。我认为这是因为提到
Arc
提示编译器应该在这里推断类型参数,而不是简单地从
=
的左侧复制它。稍微细化一下,
Into::::Into(value)
有效,但
Into:::Into(value)
无效。
impl<T> Arc<T> {
    pub fn new(data: T) -> Arc<T>
}
let _: Arc<dyn Trait> = value.into();
pub trait Into<T> {
    fn into(self) -> T;
}
impl<X, T> Into<T> for X where
    T: From<X>
impl<T> From<T> for Arc<T>