这段代码怎么了:
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)
我如何解决它?
它看起来像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)