你的两条线有根本的区别。第一个:
let _: Arc<dyn Trait> = Arc::new(value);
模式对于分辨率并不重要Arc::new()
,因为它的定义如您所指出的:
impl<T> Arc<T> {
pub fn new(data: T) -> Arc<T>
}
所以类型T
是从类型推导出来的value
那是TraitImpl
, 和Arc<TraitImpl>
被建造。
那么这个类型是隐式的未调整大小的强制对此Arc<dyn Trait>
一切都编译得很好。
但第二行是骗人的:
let _: Arc<dyn Trait> = value.into();
由于没有into
函数于TraitImpl
编译器搜索范围内的任何特征并找到Into<T>::into()
,定义为:
pub trait Into<T> {
fn into(self) -> T;
}
现在编译器想知道那是什么类型T
是。由于它是函数的返回,因此它猜测T
is Arc<dyn Trait>
。现在唯一有趣的实现Into
是在From
:
impl<X, T> Into<T> for X where
T: From<X>
Here X
is TraitImpl
and T
is Arc<dyn Trait>
。如果你看一下的含义Arc
for From
,其中包括很多,但没有一个适用。这是最相似的:
impl<T> From<T> for Arc<T>
然后,编译器会显示一些失败的候选者并发出错误。
The TL;DR;是你实际上想要进行两次转换:TraitImpl
to Arc<TraitImpl>
然后从Arc<TraitImpl>
to Arc<dyn Trait>
。但是您不能在一次强制转换中同时执行这两项操作,编译器必须以某种方式拼写出中间类型。