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_value
是 Clone
。然而编译器坚持认为 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]
implementsClone
conditionally by adding boundClone
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/