这段代码怎么了:
fn method1(a: &str) -> (String, String) {
let res = method2(a);
(res.val0(), res.val1())
}
错误是:
error: use of moved value res
我该如何解决?
答案 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)