对特征对象的引用不可克隆

Vla*_*eev 5 traits rust

为什么对trait对象的引用不可复制?此代码编译:

struct Test;

fn clone_vec<'a>(v: Vec<&'a Test>) -> Vec<&'a Test> {
    v.clone()
}

fn main() {
}
Run Code Online (Sandbox Code Playgroud)

这个没有:

trait Test {
    fn do_smt(&self);
}

fn clone_vec<'a>(v: Vec<&'a Test>) -> Vec<&'a Test> {
    v.clone()
}

fn main() {
}
Run Code Online (Sandbox Code Playgroud)

错误:

main3.rs:7:5: 7:14 error: failed to find an implementation of trait std::clone::Clone for &'a Test<no-bounds>
main3.rs:7     v.clone()
               ^~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

但是,Clone据我所知,特征是为任何类型的参考实现的:

impl<'a, T> Clone for &'a T {
    /// Return a shallow copy of the reference.
    #[inline]
    fn clone(&self) -> &'a T { *self }
}
Run Code Online (Sandbox Code Playgroud)

我只是不明白为什么&'a Test这里Test是一个特点是不可复制的.毕竟它只是一个指针.此限制禁止,例如,从去&[&'a SomeTrait]Vec<&'a SomeTrait>,它看起来像一个明显的转换,或克隆Vec<&'a SomeTrait>,如在例子.

这是非常奇怪的,只要我能够实现clone_vec()自己,没有Clone:

fn clone_vec<'a>(v: Vec<&'a Test>) -> Vec<&'a Test> {
    let mut result = Vec::new();
    for &e in v.iter() {
        result.push(e);
    }
    result
}
Run Code Online (Sandbox Code Playgroud)

huo*_*uon 6

Clone是一个普通的库特征,需要所有类型的普通(库)实现.例如,在这里Clone实现,形式如下:&T

impl<'a, T> Clone for &'a T {
    /// Return a shallow copy of the reference.
    #[inline]
    fn clone(&self) -> &'a T { *self }
}
Run Code Online (Sandbox Code Playgroud)

因此,表格的所有&T内容Clone都能...... T具体类型.而这就是硬道理:&Trait不是(还)一种形式&TT = Trait(但更确切地说是一种"原子"/原始类型,不能分成几部分),所以它没有被覆盖impl.

我们需要动态大小的类型(DST),以便编译器能够推断将Trait普通参数传递给普通参数(Nick Cameron实际上在DST实现的某些部分很难工作,因此很快就会发生这种情况).

但是,您可以手动实现Clone您感兴趣的特征,例如以下情况很好:

trait Foo {}

impl<'a> Clone for &'a Foo {
    fn clone(&self) -> &'a Foo {
        *self
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,它仅适用于在当前的箱子定义的特征,否则编译器大约有连贯性的担忧(例如,改变FooEqimpl上述的原因error: cannot provide an extension implementation where both trait and type are not defined in this crate).