这段代码(游乐场):
#[derive(Clone)]
struct Foo<'a, T: 'a> {
t: &'a T,
}
fn bar<'a, T>(foo: Foo<'a, T>) {
foo.clone();
}
Run Code Online (Sandbox Code Playgroud)
......不编译:
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`
Run Code Online (Sandbox Code Playgroud)
添加use std::clone::Clone;不会改变任何东西,因为它已经在前奏中了.
当我删除#[derive(Clone)]并手动执行Clone时Foo,它按预期编译!
impl<'a, T> Clone for Foo<'a, T> {
fn clone(&self) -> Self {
Foo {
t: self.t,
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
#[derive()]-impls和manual 之间有区别吗?She*_*ter 25
答案隐藏在错误消息中:
该方法
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> {
#[inline]
fn clone(&self) -> Foo<'a, T> {
match *self {
Foo { t: ref __self_0_0 } =>
Foo{t: ::std::clone::Clone::clone(&(*__self_0_0)),},
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,不需要绑定,因为泛型类型在引用后面.
现在,您需要Clone自己实施.这有一个Rust问题,但这是一个相对罕见的解决方法.