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