2

I have this code:

enum MyEnum1 {
  val1, 
  val2
}

struct Struct1 { 
  field1: MyEnum1,
  field2: String
}

fn fn1(a: Struct1, b: String, c: String) {
  let let1 = fn2(&a.field1);
}


fn fn2(a: &MyEnum1) {
  let a11 = *a; // error
  let s = Struct1 { field1: a11, field2: "fdsfds".to_string() };
}

fn main() {
    println!("Hello World!");
}

The error is error: cannot move out of borrowed content

I was suggested by the compiler to use ref or ref mut, I tried to use them and still that didn't help.

fn fn2(a: &MyEnum1) {
  let ref a11 = *a; // still the error
  let s = Struct1 { field1: *a11, field2: "fdsfds".to_string() };
}
  • actually the error is now in the next line, not in the line you added the `still the error` comment – oli_obk Jun 22 '15 at 08:03
  • 1
    the solution is to implement copy, the question is about "cannot move out of borrowed content", I think this is very much a duplicate – oli_obk Jun 22 '15 at 08:58

1 Answers1

3

Short answer

The function fn2 receives a reference to a MyEnum1 as a parameter, but the Struct1 contains an owned MyEnum1. This means that you are actually trying to turn a reference into an owned value, which is only possible if you copy the data.

Long answer

Your code would work if MyEnum1 implemented the Copy trait (which in turn requires implementing the Clone trait). If a type implements Copy, it will be automatically copied when you dereference it and when you assign it (for example, the i32 type in the standard library implements Copy). Try something like the following:

#[derive(Clone, Copy)]
enum MyEnum1 {
  val1, 
  val2
}

You may also choose to implement only Clone and clone the object explicitly, in case your data structure is expensive to copy (for example, the String struct in the standard library implements Clone but not Copy). Then you would need to use the following code:

#[derive(Clone)]
enum MyEnum1 {
  val1, 
  val2
}

fn fn2(a: &MyEnum1) {
  let s = Struct1 { field1: a.clone(), field2: "fdsfds".to_string() };
}

Finally, you may also choose to pass the MyEnum1 by value, instead of by reference. Then, the only change you need to apply is:

fn fn1(a: Struct1, b: String, c: String) {
  let let1 = fn2(a.field1);
}

fn fn2(a: MyEnum1) {
  let s = Struct1 { field1: a, field2: "fdsfds".to_string() };
}
aochagavia
  • 5,887
  • 5
  • 34
  • 53