estw272
estw272

Reputation: 261

Is cloning a custom struct that can't implement Copy every time you want to use it the best way to do it?

I have a struct that has a Vec field and cannot implement Copy:

#[derive(Clone, Debug)]
struct MyStruct {
    field: Vec<i32>,
}

impl MyStruct {
    fn new () -> MyStruct {
        MyStruct {
            field: vec![1, 2],
        }
    }

    fn overwrite(&mut self, strt: MyStruct) {
        self.field = strt.field;
    }
}

If I want to use it multiple times later in my code, I have to clone() it every time:

fn main() {
    let mut s = MyStruct::new();
    let s2 = MyStruct::new();

    s.overwrite(s2.clone());

    println!("{:?}", s2);
}

This works fine, but is this the best way to accomplish this task? Are there any other, more idiomatic ways?

Upvotes: 2

Views: 1438

Answers (1)

Matthieu M.
Matthieu M.

Reputation: 300139

Let's review our data handling story:

  • moving is about transferring ownership, because the original variable is no longer necessary
  • cloning is about creating a duplicate, so as to be able to use both the original and the new value independently
  • borrowing is about temporarily lending a reference for a controlled amount of time, so as to be able to use the original variable before and after (and possibly, if borrowed with & and not &mut, in a limited manner during)

In your case, you should be using borrowing here.

fn overwrite(&mut self, strt: &MyStruct) {
//                            ^
    self.field = strt.field.clone();
}

fn main() {
    let mut s = MyStruct::new();
    let s2 = MyStruct::new();

    s.overwrite(&s2);
    //          ^

    println!("{:?}", s2);
}

For an in-depth treatment of the concept, read the Rust Book. And if you come from a garbage collected language background, the chapters 4.7 to 4.10 are REALLY a must read.

Upvotes: 6

Related Questions