错误:在Rust中使用移动值res

アレッ*_*ックス 3 rust

这段代码怎么了:

fn method1(a: &str) -> (String, String) {
  let res = method2(a);
  (res.val0(), res.val1())
}
Run Code Online (Sandbox Code Playgroud)

错误是:

error: use of moved value res
Run Code Online (Sandbox Code Playgroud)

我如何解决它?

Vla*_*eev 8

它看起来像method2()返回一个不可复制的对象,而val0()val1()方法,通过价值把他们的目标:

struct SomeType { ... }

impl SomeType {
    fn val0(self) -> String { ... }
    fn val1(self) -> String { ... }
}

fn method2(a: &str) -> SomeType { ... }

fn method1(a: &str) -> (String, String) {
    let res = method2(a);
    (res.val0(), res.val1())
}
Run Code Online (Sandbox Code Playgroud)

因为SomeType它不是可自动复制的,所以它将被移动到按值取值的方法中,但是你试图做两次,这是不合理的,并且编译器报告"使用移动值"错误.

如果你不能改变SomeType它只有val0()val1()方法,没有公共字段,也没有实现Clone.那你运气不好 您将只能获得任一方法val0()val1()方法的结果,但不能同时获得两者的结果.

如果SomeType还有返回引用的方法,如下所示:

impl SomeType {
    fn ref0(&self) -> &String { ... }
    fn ref1(&self) -> &String { ... }
}
Run Code Online (Sandbox Code Playgroud)

(&str而不是&String很好)然后你可以克隆字符串:

let res = method2(a);
(res.ref0().clone(), res.ref1().clone())
Run Code Online (Sandbox Code Playgroud)

如果SomeType提供某种解构,甚至更好,例如:

impl SomeType {
    fn into_tuple(self) -> (String, String) { ... }
}
Run Code Online (Sandbox Code Playgroud)

然后它很简单:

method2(a).into_tuple()
Run Code Online (Sandbox Code Playgroud)

如果SomeType是一个双元素元组本身,你甚至不需要into_tuple(),只需method2()按原样编写调用:

method2(a)
Run Code Online (Sandbox Code Playgroud)

元组还为组和元组结构提供元组索引语法,而不是即将被弃用的元组特征.它也可以用于:

let res = method2(a);
(res.0, res.1)
Run Code Online (Sandbox Code Playgroud)

如果SomeType确实是一个相同大小的元组,那么它是多余的,但如果SomeType是一个更大的元组,那么这就是要走的路.或者你可以使用解构:

let (v1, v2, _) = method2(a);  // need as many placeholders as there are remaining elements in the tuple
(v1, v2)
Run Code Online (Sandbox Code Playgroud)