Rust 特质有时是可以移动的
我有一个特点Rust 特质有时是可以移动的,rust,traits,move-semantics,Rust,Traits,Move Semantics,我有一个特点 trait Trait<T> where T: Data { fn m1(&self) -> bool; fn m2(self) -> Box<dyn Trait<T>>; } 因此,如果无法移动trait对象,为什么new\u vec.push(trait\u object)可以工作?dyn trait是一个trait对象,它与实现trait的受约束类型变量不同 trait对象使用动态分派,并且在编
trait Trait<T>
where T: Data
{
fn m1(&self) -> bool;
fn m2(self) -> Box<dyn Trait<T>>;
}
因此,如果无法移动trait对象,为什么new\u vec.push(trait\u object)
可以工作?dyn trait
是一个trait对象,它与实现trait的受约束类型变量不同
trait对象使用动态分派,并且在编译时没有已知的大小-这就是为什么您几乎总是在&
引用或装箱后看到trait对象的原因。这就是为什么错误消息说无法静态确定dyn Trait的大小
您的特性可以用于任何具体(大小
)类型。例如,对于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())
}
}
i32的impl特性
哪里
T:数据,
{
fn m1(和自身)->bool{
真的
}
//因为i32的大小不同,所以可以在这里使用self
fn m2(自)->盒{
使\u装箱\u特征\u t(字符串::new())
}
}
为什么我可以像Vec
那样在容器中推送trait对象:
let trait_object: Box<dyn Trait<T>> = e;
let mut new_vec = Vec::new();
new_vec.push(trait_object)
这是因为示例中的trait对象已装箱
dyn Trait
未指定大小,但Box
的大小在编译时已知。大小是两个指针的大小,因为装箱的trait对象的布局始终是指向数据的指针和指向类型实现trait
的vtable的指针。您可以在通用上下文中调用m2
。您不能将它用于dyn trait对象:fn foo(t:T2){t.m2();}
这不是静态绑定吗??由于T2
始终是一种特质,因此没有动态调度,因此t.m2()
有效?是的,你是对的。只要您的类型是大小的
,您就可以调用m2
,dyn对象不是大小的
,但泛型类型是大小的
,除非您使用:?大小的
解除约束。因此,当添加到容器时,它会移动框
,而通过方法调用,它会尝试移动框
中的内容?