我的代码:
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`
我该如何解决?我应该将&
添加到'fn2 and
fn3 ? Or
mut`的参数中吗?我无法理解如何解决这些错误。
答案 0 :(得分:3)
这些错误来自Rust中最重要的概念 - 所有权。您应该阅读the official book,尤其是关于ownership的章节 - 这有助于您理解“如何解决此类错误”。
简而言之,特别是在您的代码中,问题是String
是一个不可复制的类型,即String
值在传递给函数或分配给局部变量时不会被复制,它们是移动。这意味着无论他们以前在哪里,都无法从那里访问它们。
让我们来看看你的功能:
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 {
//....
}
此处的所有类型都不能自动复制(它们不实现Copy
特征)。 String
不可复制,因为它是一个堆分配的字符串,复制需要一个新的分配(一个昂贵的操作,最好不要隐式),MyEnum1
不可复制,因为它没有实现{{1 (例如,Copy
;并且不清楚它是否可以复制,因为您没有提供其变体),#[deriving(Copy, Clone)]
不可复制,因为它包含不可复制的类型。
在Struct1
中,您调用fn1
,传递fn2
并获得field1
。然后,您立即将此String
传递给String
。由于fn3
不可复制,因此String
中存储的内容已移动到被调用函数中,导致let1
无法访问。这就是“使用移动值”错误的原因。 (您提供的代码不会导致“使用移动值:let1
”错误,因此它可能来自您省略的部分,但基本思想绝对相同)
有几种方法可以解决这些错误,但最自然和最常见的方法确实是使用借用的引用。通常,如果您只想读取函数中的某些不可复制值,则应通过引用将其传递给它:
a.field1
对于字符串和数组,更好的方法是传递切片:
fn use_myenum(e: &MyEnum1)
您可以在书中找到有关切片的更多信息,here。