派生特征会导致意外的编译器错误,但是手动实现有效

此代码(操场):


#[derive(Clone)]

struct Foo<'a, T: 'a> {

    t: &'a T,

}


fn bar<'a, T>(foo: Foo<'a, T>) {

    foo.clone();

}

...无法编译:


error: no method named `clone` found for type `Foo<'a, T>` in the current scope

  --> <anon>:7:9

   |>

16 |>     foo.clone();

   |>         ^^^^^

note: the method `clone` exists but the following trait bounds were not satisfied: `T : std::clone::Clone`

help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `clone`, perhaps you need to implement it:

help: candidate #1: `std::clone::Clone`

添加use std::clone::Clone;并不会改变任何内容,因为它已经在序幕中了。


当我删除#[derive(Clone)]并手动实现Clone时Foo,它会按预期编译!


impl<'a, T> Clone for Foo<'a, T> {

    fn clone(&self) -> Self {

        Foo {

            t: self.t,

        }

    }

}

这里发生了什么?


#[derive()]-impls和手动的之间有区别吗?

这是编译器错误吗?

还有我没想到的东西?


神不在的星期二
浏览 527回答 2
2回答

天涯尽头无女友

答案隐藏在错误消息中:该方法clone存在,但不满足以下特征范围:T : std::clone::Clone当您派生Clone(以及许多其他自动派生的类型)时,它会Clone在所有通用类型上添加一个界限。使用rustc -Z unstable-options --pretty=expanded,我们可以看到它变为:impl <'a, T: ::std::clone::Clone + 'a> ::std::clone::Clone for Foo<'a, T> {&nbsp; &nbsp; #[inline]&nbsp; &nbsp; fn clone(&self) -> Foo<'a, T> {&nbsp; &nbsp; &nbsp; &nbsp; match *self {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Foo { t: ref __self_0_0 } =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Foo{t: ::std::clone::Clone::clone(&(*__self_0_0)),},&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}在这种情况下,不需要绑定,因为泛型类型在引用后面。现在,您将需要实现Clone自己。有一个Rust问题,但这是一种相对罕见的解决方法。
打开App,查看更多内容
随时随地看视频慕课网APP