此代码(playground):

#[derive(Clone)]
struct Foo<'a, T: 'a> {
    t: &'a T,
}

fn bar<'a, T>(foo: Foo<'a, T>) {
    foo.clone();
}

... 不编译:

error[E0599]: no method named `clone` found for struct `Foo<'a, T>` in the current scope
   --> src/main.rs:16:9
    |
3   | struct Foo<'a, T: 'a> {
    | ---------------------
    | |
    | method `clone` not found for this
    | doesn't satisfy `Foo<'_, T>: std::clone::Clone`
...
16  |     foo.clone();
    |         ^^^^^ method not found in `Foo<'a, T>`
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `T: std::clone::Clone`
            which is required by `Foo<'_, T>: std::clone::Clone`
help: consider restricting the type parameter to satisfy the trait bound
    |
3   | struct Foo<'a, T: 'a> where T: std::clone::Clone {
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^

use std::clone::Clone;不会改变任何事情,因为它已经出现在前奏曲中了.

当我移除#[derive(Clone)]并手动执行Clone for Foo时,它是compiles as expected

impl<'a, T> Clone for Foo<'a, T> {
    fn clone(&self) -> Self {
        Foo {
            t: self.t,
        }
    }
}

这是怎么回事?

  • #[derive()]个IMPL和手动的有区别吗?
  • 这是编译器错误吗?
  • 还有什么我没想到的?

推荐答案

答案隐藏在错误消息中:

    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `T: std::clone::Clone`
            which is required by `Foo<'_, T>: std::clone::Clone`

当您派生Clone(以及许多其他自动派生的类型)时,它会在all个泛型类型上添加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)),},
        }
    }
}

this种情况下,不需要绑定,因为泛型类型位于引用后面.

现在,您需要自己实现Clone.There's a Rust issue for this,但这是一个相对罕见的有解决办法的 case .

Rust相关问答推荐

捕获Rust因C++异常而产生panic

在actix—web中使用Redirect或NamedFile响应

如何容器化Linux上基于Rust的Windows应用程序的编译过程?

如何使用字符串迭代器执行查找?

有没有办法模仿对象安全克隆?

`*mut[T]`与`*mut T`的区别

关于 map 闭合求和的问题

对于rustc编译的RISC-V32IM二进制文件,llvm objdump没有输出

如何初始化选项<;T>;数组Rust 了?

如何轮询 Pin>?

类型生命周期绑定的目的是什么?

write_buffer 不写入缓冲区而是输出零 WGPU

`use` 和 `crate` 关键字在 Rust 项目中效果不佳

unwrap 选项类型出现错误:无法移出共享引用后面的*foo

Rust并发读写引起的死锁问题

如何在 Emacs Elisp 中获得类似格式化的 LSP?

将原始可变指针传递给 C FFI 后出现意外值

Rust 将特性传递给依赖项

如何将切片推入数组?

如何重写这个通用参数?