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对象不是
大小的
,但泛型类型是
大小的
,除非您使用
:?大小的
解除约束。因此,当添加到容器时,它会移动
,而通过方法调用,它会尝试移动
中的内容?