Deriving the Clone
trait for a struct containing a reference to object of generic type (Unless it has Clone
bound. In that case cloning work as expected) will generate clone()
method which returns a reference to object but not a new object.
I have the code:
#[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()
}
Which will cause an error:
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>`
Why does derive behave this way?
Following manual implementation allow to avoid this obstacle but unpleasant.
impl<'a, T: 'a> Clone for A<'a, T>{
fn clone(&self)->Self{
A{ref_generic: self.ref_generic}
}
}
Object cloning refers to the creation of an exact copy of an object. It creates a new instance of the class of the current object and initializes all its fields with exactly the contents of the corresponding fields of this object. Using Assignment Operator to create a copy of the reference variable.
Trait std::clone::Clone1.0. A common trait for the ability to explicitly duplicate an object. Differs from Copy in that Copy is implicit and extremely inexpensive, while Clone is always explicit and may or may not be expensive.
Object class is in java. lang package and MyClass is in GoodQuestions package. So clone() method becomes a private member of MyClass class. That explains why you are unable to access clone() method from TestSingleTon class.
You are not calling A::clone()
. You are calling &A::clone()
, i.e. you are cloning the reference, not the object.
The compiler would actually prefer to call A::clone()
, because the argument matches more precisely (Clone::clone
takes a &self
, so the single ref matches exactly, instead of requiring auto-ref for the call to the reference clone), but it can't. (You can see that by looking at the error message you get when you try to do (*a).clone()
instead.) This is because the auto-derived Clone
naively implements it as:
impl <'a, T: Clone + 'a> Clone for A<'a, T> {
fn clone(&self) -> Self { Self { ref_generic: self.ref_generic } }
}
Note the Clone
bound on T
. That bound is not necessary, but the auto-derivation still requires it. This is bug #26925.
Your test_call
function does not have a bound on T
, which means that the derived Clone
impl for A
is not available, so the compiler falls back to the only Clone
impl it can call, which is the one for &A
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With