pdiffley
pdiffley

Reputation: 713

How to clone struct with a mutable reference

I have a struct containing a mutable reference (MyStruct2) that I need to clone, so I derived the Clone method for that struct:

#[derive(Clone)]
struct MyStruct {
    val: usize,
}

#[derive(Clone)]
struct MyStruct2<'a> {
    struct_reference: &'a mut MyStruct
}

However, when I compile this code, I get the following error message:

src/main.rs:419:3: 419:37 error: the trait `core::clone::Clone` is not implemented for the type `&mut MyStruct` [E0277]
src/main.rs:419         struct_reference: &'a mut MyStruct
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:417:11: 417:16 note: in this expansion of #[derive_Clone] (defined in src/main.rs)
src/main.rs:419:3: 419:37 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:419:3: 419:37 help: the following implementations were found:
src/main.rs:419:3: 419:37 help:   <MyStruct as core::clone::Clone>
src/main.rs:419:3: 419:37 note: required by `core::clone::Clone::clone`
error: aborting due to previous error

If I make the reference immutable, then the code compiles.

#[derive(Clone)]
struct MyStruct {
    val: usize,
}

#[derive(Clone)]
struct MyStruct2<'a> {
    struct_reference: &'a MyStruct
}

It seems that even though clone is derived for the struct MyStruct, it is not derived for a mutable reference to MyStruct.

Is there a way to clone a mutable reference to a struct and to clone a struct containing a mutable reference?

Upvotes: 7

Views: 8089

Answers (1)

wimh
wimh

Reputation: 15232

It is possible to have multiple non-mutable references to the same resource. So in the code which compiles, you will get two references to the same MyStruct when MyStruct2 is cloned.:

#[derive(Clone)]
struct MyStruct {
    val: usize,
}

#[derive(Clone)]
struct MyStruct2<'a> {
    struct_reference: &'a MyStruct
}

However, it is only possible to have a single mutable reference to a resource. So it is not possible to automatically implement Clone for MyStruct2. You can implement it yourself, it will look like this:

impl<'a> Clone for MyStruct2<'a> {
    fn clone(&self) -> MyStruct2<'a> {
        // your code here
    }
}

But you still can't have two mutable references to the same MyStruct. You also can't create a clone of MyStruct which lives long enough to return in the clone function. So you would have to modify your data structure to make this possible.

Upvotes: 9

Related Questions