Clone
trait的文档说明了“如果所有字段都是Clone
,这个trait可以与#[derive]
一起使用。”我正在努力解决一个所有字段 * 都是 * 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
?
1条答案
按热度按时间mkshixfv1#
文档中的第二句应该对此进行解释
对于泛型结构,
#[derive]
通过在泛型参数上添加绑定的Clone
来有条件地实现Clone
。这就是derive宏的工作方式。而且这也是它 * 能够 * 工作的唯一方式,因为过程宏的执行发生在编译器能够推理这些trait边界是否必要之前。幸运的是,你可以通过手动实现
Clone
trait来解决这个问题。