Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clone struct with a mutable reference

Tags:

rust

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?

like image 839
pdiffley Avatar asked Nov 25 '16 18:11

pdiffley


1 Answers

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.

like image 162
wimh Avatar answered Sep 24 '22 06:09

wimh