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

时间:2014-12-01 08:57:15

标签: rust

这段代码怎么了:

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

错误是:

error: use of moved value res

我该如何解决?

1 个答案:

答案 0 :(得分: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())
}

由于SomeType不能自动复制,因此会将其移动到按值取值的方法中,但是您尝试执行两次,这是不合理的,并且编译器报告“使用移动值”错误。

如果您无法更改SomeType,并且只有val0()val1()方法,则没有公共字段且未实现Clone。那你运气不好您只能获得val0()val1()方法的结果,但不能同时获得结果。

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

impl SomeType {
    fn ref0(&self) -> &String { ... }
    fn ref1(&self) -> &String { ... }
}

&str代替&String也很好) 然后你可以克隆字符串:

let res = method2(a);
(res.ref0().clone(), res.ref1().clone())

如果SomeType提供某种解构,那就更好了,例如:

impl SomeType {
    fn into_tuple(self) -> (String, String) { ... }
}

然后很简单:

method2(a).into_tuple()

如果SomeType本身是一个双元素元组,则您甚至不需要into_tuple(),只需按method2()调用即可:

method2(a)

元组还为元组和元组结构提供tuple indexing syntax,而不是即将弃用tuple traits。它也可以使用:

let res = method2(a);
(res.0, res.1)

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

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