Rust 坚持认为可克隆结构的通用参数也必须实现 Clone

标签 rust

documentation of the Clone trait指出“如果所有字段都是 #[derive] ,则此特征可以与 Clone 一起使用。”我正在努力解决所有字段都是 Clone 的情况,但仍得出 Clone不起作用。

考虑以下简化示例 ( Playground link ):

use std::fmt;
use std::rc::Rc;

trait Printer: Clone {
    fn print(&self) -> ();
}

#[derive(Clone)]
struct ClosurePrinter<T: fmt::Display> {
    get_value: Rc<dyn Fn() ->T>,
}

impl<T: fmt::Display> ClosurePrinter<T> {
    pub fn new(get_value: Rc<dyn Fn() -> T>) -> ClosurePrinter<T> {
        ClosurePrinter { get_value }
    }
}

impl<T: fmt::Display> Printer for ClosurePrinter<T> {
    fn print(&self) -> () {
        println!("{}", (self.get_value)())
    }
}

结构ClosurePrinter有一个字段,get_value: Rc<dyn Fn() -> T>Rc实现Clone ,所以我假设 get_valueClone 。然而编译器坚持认为 T必须是Clone ,还有:

error[E0277]: the trait bound `T: Clone` is not satisfied
  --> src/lib.rs:19:23
   |
19 | impl<T: fmt::Display> Printer for ClosurePrinter<T> {
   |                       ^^^^^^^ the trait `Clone` is not implemented for `T`
   |
note: required because of the requirements on the impl of `Clone` for `ClosurePrinter<T>`
  --> src/lib.rs:8:10
   |
8  | #[derive(Clone)]
   |          ^^^^^
note: required by a bound in `Printer`
  --> src/lib.rs:4:16
   |
4  | trait Printer: Clone {
   |                ^^^^^ required by this bound in `Printer`
   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
   |
19 | impl<T: fmt::Display + std::clone::Clone> Printer for ClosurePrinter<T> {
   |                      +++++++++++++++++++

为什么编译器坚持 T必须是Clone

最佳答案

文档中的第二句话应该解释这一点

For a generic struct, #[derive] implements Clone conditionally by adding bound Clone on generic parameters.

这就是派生宏的工作原理。此外,这是它可以工作的唯一方式,因为过程宏执行发生在编译器可以推断这些特征边界是否必要之前。幸运的是,您可以通过手动实现 Clone 特征来解决这个问题。

use std::fmt;
use std::rc::Rc;

struct ClosurePrinter<T: fmt::Display> {
    get_value: Rc<dyn Fn() ->T>,
}

impl<T: fmt::Display> Clone for ClosurePrinter<T> {
    fn clone(&self) -> Self {
         let get_value = Rc::clone(&self.get_value);
         Self { get_value }
    }
}

关于Rust 坚持认为可克隆结构的通用参数也必须实现 Clone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74085761/

相关文章:

json - 如何在 Serde 中(反)序列化强类型的 JSON 字典?

rust - 内部可变性与数据隐藏以固定可变借用的所指对象

sql-server - SQLx 到 Mssql 连接字符串

rust - 如何允许函数使用整数或 float ?

rust - 如何叠加数据结构?

rust - 你如何解决在 Rust 中可变地借用不同的比赛武器的需要?

struct - 在 Rust 中拥有多个具有相同属性的结构的惯用方法是什么?

multithreading - 为什么这些线程在完成工作之前退出?

string - 展开跳过的 Chars 迭代器

unit-testing - 在 Rust 中进行单元测试后清理的好方法是什么?