Hello people,I have a structure which is auto generated, it doesn't implement clone trait.I want to use this structure at a different place I have imported the structure with use.now i want to implement clone here.How do i achieve this?
I have tried impl Clone for mystruct{}
this is giving following error.
`x::y::z::mystruct` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
jofas
June 13, 2023, 9:47am
2
You can't implement a foreign trait (Clone
from the standard library) on a foreign type (x::y::z::mystruct
from the x
crate).
Easiest would probably be to auto-generate the struct with a Clone
implementation (if you can control that or ask someone who has control to add it).
Otherwise you have to wrap mystruct
in a different type and implement Clone
on that one. This is commonly referred to as the newtype
pattern:
struct MyStruct(x::y::z::mystruct);
impl Clone for MyStruct {
fn clone(&self) -> Self {
// clone x::y::z::mystruct here and return MyStruct(clone)
}
}
Or you could create your own trait that works like Clone
and implement that on x::y::z::mystruct
:
trait MyClone {
fn my_clone(&self) -> Self;
}
impl MyClone for x::y::z::mystruct {
fn my_clone(&self) -> Self {
todo!()
}
}
jbe
June 13, 2023, 9:55am
3
Here an example for the mentioned newtype pattern:
mod othercrate {
#[derive(Debug)]
pub struct NotCloneable {
pub name: String,
}
}
pub struct Foo(pub othercrate::NotCloneable);
impl Clone for Foo {
fn clone(&self) -> Foo {
Foo(othercrate::NotCloneable {
name: self.0.name.clone(),
})
}
}
fn main() {
let nc = othercrate::NotCloneable {
name: "Hello World!".to_string(),
};
//let nc2 = nc.clone(); // fails
let wrapped = Foo(nc);
let wrapped2 = wrapped.clone();
let wrapped3 = wrapped.clone();
let wrapped4 = wrapped.clone();
let nc: othercrate::NotCloneable = wrapped.0;
let nc2: othercrate::NotCloneable = wrapped2.0;
let nc3: othercrate::NotCloneable = wrapped3.0;
let nc4: othercrate::NotCloneable = wrapped4.0;
println!("{nc:?}");
println!("{nc2:?}");
println!("{nc3:?}");
println!("{nc4:?}");
}
(Playground )
Thank you for the explanation.
I have one more issue in regards this, now i want to implement clone for Vec<MyStruct>
. i have already implemented custom clone (fn clone2(&self)->Self
) for MyStruct (since MyStruct
is defined else where and i can't derive clone),now how can i achieve clone
for Vec<MyStruct>
?
jofas
June 14, 2023, 8:02am
5
You could implement your custom MyClone
for Vec<MyStruct>
as well. Or even better, make it generic over T
where T: MyClone
:
impl<T: MyClone> MyClone for Vec<T> {
fn my_clone(&self) -> Self {
self.iter().map(|x| x.my_clone()).collect()
}
}
2 Likes
khimru
June 14, 2023, 9:23am
6
Why doesn't it implement close? You can still use derive
even with autogenerated structs.
1 Like
The structs are generated everytime i build, I can't disclose further but yeah i can't change the generated structures.
system
Closed
September 12, 2023, 9:50am
9
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.