为什么在调用带有按值自取值的参数并同时调用方法的方法时,为什么要借用移动值呢?

时间:2019-03-12 08:52:19

标签: rust borrow-checker

我遇到了一个问题,该问题迫使我将一个不错的oneliner分成一个中间为{}的{​​{1}}块。我根本不清楚这个原因。在这个最小的示例中,我能够找出问题所在:

let

我给struct AB { a: u8, b: u8, } impl AB { fn foo(&self) -> String { String::from("foo") } fn bar(self, x: String) -> String { format!("{} - {} - {}!", x, self.a, self.b) } } fn main() { let x = AB { a: 3, b: 5 }; let result = x.bar(x.foo()); println!("{}", result); } 函数的参数赋值是在调用bar之前 求值。 bar在执行期间借用了foo,但是当它返回其x时,借用已完成,因为String不是承载String的生存期的引用。当x被呼叫时,bar的借用应该已经结束。

但是,编译器不同意:

foo

我不同意error[E0382]: borrow of moved value: `x` --> src/main.rs:17:24 | 17 | let result = x.bar(x.foo()); | - ^ value borrowed here after move | | | value moved here | = note: move occurs because `x` has type `AB`, which does not implement the `Copy` trait 确实会移动bar的事实。我的问题是这样的说法,即x在搬迁发生后借入foo

一个简单(但难看)的修复程序:

x

struct AB { a: u8, b: u8, } impl AB { fn foo(&self) -> String { String::from("foo") } fn bar(self, x: String) -> String { format!("{} - {} - {}!", x, self.a, self.b) } } fn main() { let x = AB { a: 3, b: 5 }; let y = x.foo(); let result = x.bar(y); println!("{}", result); } 分配给中间变量x.foo()可以很好地编译,这证实了我的期望,即一旦y返回,借入确实已经结束了,但是为什么这样做有效?关于评估顺序,我是否不了解?为什么我不能摆脱中间的foo

1 个答案:

答案 0 :(得分:4)

出于借款目的,评估顺序是从左到右。

这意味着{{1}中调用NaN的主题,即“移出” bar,在{{1 }}调用,因此编译器认为该变量已从中移出。

对于外部提及是可变借用的类似情况,RFC 2025已被接受为解决方案,但尚未实现。不幸的是,该RFC似乎没有涵盖您的情况,因为外部使用是一个举动。