有时可以移动特征
Trait can be sometimes moved
我有一个特征看起来像
trait Trait<T>
where T: Data
{
fn m1(&self) -> bool;
fn m2(self) -> Box<dyn Trait<T>>;
}
为什么 m2
方法 self
甚至被允许?它不像任何 trait impls 可以调用该方法,因为:
cannot move a value of type dyn Trait<T>: the size of dyn Trait<T> cannot be statically determined
这个错误是有道理的,但为什么我可以 push
像 Vec
这样的容器中的特征对象:
let trait_object: Box<dyn Trait<T>> = e;
let mut new_vec = Vec::new();
new_vec.push(trait_object)
那么,如果无法移动特征对象,为什么 new_vec.push(trait_object)
有效?
dyn Trait<T>
是一个特征对象,它不同于具有实现特征的约束类型变量。
特征对象使用动态调度并且在 compile-time 处不知道大小 - 这就是为什么您几乎总是看到 &
引用或装箱后的特征对象。这就是错误消息显示 the size of dyn Trait<T> cannot be statically determined
.
的原因
您的特征可以针对任何具体 (Sized
) 类型实现。例如,对于 i32
:
impl Trait<String> for i32
where
T: Data,
{
fn m1(&self) -> bool {
true
}
// Can take self here because i32 is Sized
fn m2(self) -> Box<dyn Trait2<T>> {
make_boxed_trait_t(String::new())
}
}
why can I can push
trait objects in a container like Vec
like so:
之所以可行,是因为您的示例中的特征对象被装箱了。 dyn Trait<T>
未调整大小,但 Box<dyn Trait<T>>
的大小在编译时已知。 size是两个指针的大小,因为一个装箱的trait对象的布局总是一个指向数据的指针和一个指向Trait
.
类型实现的vtable的指针
我有一个特征看起来像
trait Trait<T>
where T: Data
{
fn m1(&self) -> bool;
fn m2(self) -> Box<dyn Trait<T>>;
}
为什么 m2
方法 self
甚至被允许?它不像任何 trait impls 可以调用该方法,因为:
cannot move a value of type dyn Trait<T>: the size of dyn Trait<T> cannot be statically determined
这个错误是有道理的,但为什么我可以 push
像 Vec
这样的容器中的特征对象:
let trait_object: Box<dyn Trait<T>> = e;
let mut new_vec = Vec::new();
new_vec.push(trait_object)
那么,如果无法移动特征对象,为什么 new_vec.push(trait_object)
有效?
dyn Trait<T>
是一个特征对象,它不同于具有实现特征的约束类型变量。
特征对象使用动态调度并且在 compile-time 处不知道大小 - 这就是为什么您几乎总是看到 &
引用或装箱后的特征对象。这就是错误消息显示 the size of dyn Trait<T> cannot be statically determined
.
您的特征可以针对任何具体 (Sized
) 类型实现。例如,对于 i32
:
impl Trait<String> for i32
where
T: Data,
{
fn m1(&self) -> bool {
true
}
// Can take self here because i32 is Sized
fn m2(self) -> Box<dyn Trait2<T>> {
make_boxed_trait_t(String::new())
}
}
why can I can
push
trait objects in a container likeVec
like so:
之所以可行,是因为您的示例中的特征对象被装箱了。 dyn Trait<T>
未调整大小,但 Box<dyn Trait<T>>
的大小在编译时已知。 size是两个指针的大小,因为一个装箱的trait对象的布局总是一个指向数据的指针和一个指向Trait
.