为什么不能用let _创建特征对象:Arc< dyn Trait> = value.into()?
use std::sync::Arc;
trait Trait {}
struct TraitImpl {}
impl Trait for TraitImpl {}
fn main() {
let value = TraitImpl {};
let _: Arc<dyn Trait> = Arc::new(value); // compiles
let _: Arc<dyn Trait> = value.into(); // doesn't compile
}
结果:
error[E0277]: the trait bound `std::sync::Arc<dyn Trait>: std::convert::From<TraitImpl>` is not satisfied
--> src/main.rs:10:35
|
10 | let _: Arc<dyn Trait> = value.into(); // doesn't compile
| ^^^^ the trait `std::convert::From<TraitImpl>` is not implemented for `std::sync::Arc<dyn Trait>`
|
= help: the following implementations were found:
<std::sync::Arc<T> as std::convert::From<T>>
<std::sync::Arc<T> as std::convert::From<std::boxed::Box<T>>>
<std::sync::Arc<[T]> as std::convert::From<&[T]>>
<std::sync::Arc<[T]> as std::convert::From<std::vec::Vec<T>>>
and 8 others
= note: required because of the requirements on the impl of `std::convert::Into<std::sync::Arc<dyn Trait>>` for `TraitImpl`
(游乐场 )
为什么Arc::new(value)
可以编译,而value.into()
不可以编译?我不明白为什么 Arc<T>::new()
满意,而 From<T>::from
不是.
Why does Arc::new(value)
compile but not value.into()
? I don't understand why Arc<T>::new()
is satisfied while From<T>::from
isn't.
impl<T> Arc<T> {
pub fn new(data: T) -> Arc<T>
}
impl<T> From<T> for Arc<T> {
fn from(t: T) -> Arc<T>
}
您的两行有根本的区别.第一个:
There is a fundamental difference in your two lines. The first one:
let _: Arc<dyn Trait> = Arc::new(value);
该模式对于Arc::new()
的分辨率并不重要,因为它的定义如您所述:
The pattern is not important for the resolution of Arc::new()
, since it is defined as you noted:
impl<T> Arc<T> {
pub fn new(data: T) -> Arc<T>
}
因此从value
的类型TraitImpl
推导类型T
,并创建了Arc<TraitImpl>
.
然后,将这种类型隐式地对大小Arc<dyn Trait>
进行无限制强制,然后所有编译就可以了.
So the type T
is deduced from the type of value
that is TraitImpl
, and an Arc<TraitImpl>
is created.
Then this type is implicitly unsized-coerced to that Arc<dyn Trait>
and all compiles fine.
但是第二行比较棘手:
let _: Arc<dyn Trait> = value.into();
由于TraitImpl
中没有into
函数,因此编译器在范围内搜索任何特征并找到Into<T>::into()
,其定义为:
Since there is not an into
function in TraitImpl
the compiler searches any trait in scope and finds Into<T>::into()
, that is defined as:
pub trait Into<T> {
fn into(self) -> T;
}
现在,编译器想知道T
是什么类型.由于它是函数的返回,因此它猜测T
是Arc<dyn Trait>
.现在,Into
的唯一有趣的实现是根据From
:
Now the compiler wonders what type would that T
be. Since it is the return of the function, it guesses that T
is Arc<dyn Trait>
. Now the only interesting implementation of Into
is in terms of From
:
impl<X, T> Into<T> for X where
T: From<X>
此处X
是TraitImpl
,而T
是Arc<dyn Trait>
.如果您查看Arc
对From
的暗示,则其中包括很多,但没有一个适用.这是最相似的:
Here X
is TraitImpl
and T
is Arc<dyn Trait>
. If you look at the impls of Arc
for From
, it includes a lot of them, but none that applies. This is the most similar:
impl<T> From<T> for Arc<T>
然后,编译器将显示一些失败的候选对象并发出错误.
Then, the compiler shows a few of the failing candidates and emits an error.
TL; DR; 实际上是要进行两次转换:从TraitImpl
到Arc<TraitImpl>
,然后从Arc<TraitImpl>
到Arc<dyn Trait>
.但是您不能一次执行两个操作,编译器必须以某种方式阐明中间类型.
The TL;DR; is that you actually want to do two conversions: from TraitImpl
to Arc<TraitImpl>
and then from Arc<TraitImpl>
to Arc<dyn Trait>
. But you cannot do both in a single coertion, the compiler must have the intermediate type spelled out somehow.