引用 trait 对象不可克隆

5

为什么trait对象的引用不可克隆?以下代码是可以编译的:

struct Test;

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

fn main() {
}

这个不行:
trait Test {
    fn do_smt(&self);
}

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

fn main() {
}

错误:

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()
               ^~~~~~~~~

然而,我所见过的是Clone特质适用于任何类型的引用:
impl<'a, T> Clone for &'a T {
    /// Return a shallow copy of the reference.
    #[inline]
    fn clone(&self) -> &'a T { *self }
}

我不明白为什么一个实现了trait的变量Test不能被克隆,毕竟它只是一个指针。这个限制阻止了例如从&[&'a SomeTrait]Vec<&'a SomeTrait>这样显然的转换,或者像示例中那样克隆一个Vec<&'a SomeTrait>
很奇怪的是,即使没有Clone,我也可以自己实现clone_vec()
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
}
1个回答

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 }
}

因此,所有形式为 &T 的内容都可以进行克隆,其中T 是具体类型。这是关键: &Trait 还不是形如 &T 的带有 T = Trait 的类型(而是一个“原子”/ 原始类型,无法分解成部分),因此它不适用于该impl
我们需要动态大小的类型(DST)来使编译器能够推理出将普通旧的Trait传递作为通用参数(Nick Cameron正在努力实现DST实现的某些部分,所以这将很快实现)。
但是,您可以手动为感兴趣的 traits 实现Clone,例如以下方法非常有效:
trait Foo {}

impl<'a> Clone for &'a Foo {
    fn clone(&self) -> &'a Foo {
        *self
    }
}

然而,它只适用于您当前箱中定义的特质,否则编译器会对一致性产生顾虑(例如,在上面的impl中将Foo更改为Eq会导致error: cannot provide an extension implementation where both trait and type are not defined in this crate错误)。


这正是我怀疑的。我会等待DST。看起来它将是一个壮观的变化,有很多新功能可以方便我们的生活:)非常感谢! - Vladimir Matveev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接