My code:
enum MyEnum1 {
//....
}
struct Struct1 {
field1: MyEnum1,
field2: String
}
fn fn1(a: Struct1, b: String, c: String) -> String {
let let1 = fn2(a.field1);
let let2 = fn3(let1, b, c);
format!("{} something 123 {}", let1, let2)
}
fn fn2(a: MyEnum1) -> String {
//....
}
fn fn3(a: MyEnum1, b: Struct1) -> String {
//....
}
error: use of moved value: `a.field1`
error: use of moved value: `let1`
How can I fix them? Should I add &
to the parameters of 'fn2and
fn3? Or
mut`? I can't understand the idea of how to fix these kind of errors.
These errors come from the most important concept in Rust - ownership. You should read the official book, especially the chapter on ownership - this would help you understand "how tho fix this kind of errors".
In short, specifically in your code, the problem is that
String
is a non-copyable type, that is,String
values are not copied when passed to functions or assigned to local variables, they are moved. This means that wherever they were before, they are not accessible from there anymore.Let's look at your function:
All types here are not automatically copyable (they don't implement
Copy
trait).String
is not copyable because it is a heap-allocated string and copying would need a fresh allocation (an expensive operation which better be not implicit),MyEnum1
is not copyable because it does not implementCopy
(with#[deriving(Copy, Clone)]
, for example; and it is unclear if it can be made copyable because you didn't provide its variants), andStruct1
is not copyable because it contains non-copyable types.In
fn1
you invokefn2
, passing itfield1
and getting aString
back. Then you immediately passes thisString
tofn3
. BecauseString
is not copyable, whatever is stored inlet1
is moved into the called function, makinglet1
inaccessible. This is what "use of moved value" error is about. (The code you provided can't cause "use of moved value:a.field1
" error, so it probably came from the parts you omitted, but the basic idea is absolutely the same)There are several ways to fix these errors, but the most natural and common one is indeed to use borrowed references. In general if you only want to read some non-copyable value in a function you should pass it there by reference:
For strings and arrays, however, the better way would be to pass slices:
You can find more on slices in the book, here.