为包含对泛型类型对象的引用的结构派生Clone
特征(除非它已绑定Clone
。在这种情况下,克隆按预期工作)将生成clone()
方法返回对象的引用,但不返回新对象。
我有代码:
#[derive(Clone)]
struct A<'a, T: 'a>{
ref_generic: &'a T
}
fn test_call<'a, T: 'a>(a: &A<'a, T>)->A<'a, T>{
a.clone()
}
哪会导致错误:
error[E0308]: mismatched types
--> src/lib.rs:15:5
|
14 | fn test_call<'a, T: 'a>(a: &A<'a, T>)->A<'a, T>{
| -------- expected `A<'a, T>` because of return type
15 | a.clone()
| ^^^^^^^^^ expected struct `A`, found &A<'_, T>
|
= note: expected type `A<'a, T>`
found type `&A<'_, T>`
为什么派生表现得这样?
遵循手动实施可以避免这种障碍,但令人不快。
impl<'a, T: 'a> Clone for A<'a, T>{
fn clone(&self)->Self{
A{ref_generic: self.ref_generic}
}
}
答案 0 :(得分:7)
您没有致电A::clone()
。您正在调用&A::clone()
,即您正在克隆引用,而不是对象。
编译器实际上更愿意调用A::clone()
,因为参数匹配更精确(Clone::clone
需要&self
,所以单个ref完全匹配,而不需要自动引用对参考克隆的调用),但它不能。 (您可以通过查看尝试执行(*a).clone()
时收到的错误消息来查看。)这是因为自动派生的Clone
天真地将其实现为:
impl <'a, T: Clone + 'a> Clone for A<'a, T> {
fn clone(&self) -> Self { Self { ref_generic: self.ref_generic } }
}
请注意Clone
上绑定的T
。这种约束不是必需的,但自动推导仍然需要它。这是bug #26925。
您的test_call
函数在T
上没有绑定,这意味着Clone
的派生A
impl不可用,因此编译器会回退到只有Clone
impl它可以调用,这是&A
。