cannot move out of borrowed content - ref doesn

2019-07-23 14:21发布

问题:

This question already has an answer here:

  • “cannot move out of borrowed context” and “use of moved value” 1 answer

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() };
}

回答1:

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() };
}


标签: rust