我正在与借用检查器作斗争。我有两个类似的代码片段,一个像我预期的那样工作,另一个则不是。
能够按照我的期望工作的代码:
mod case1 {
struct Foo {}
struct Bar1 {
x: Foo,
}
impl Bar1 {
fn f<'a>(&'a mut self) -> &'a Foo {
&self.x
}
}
// only for example
fn f1() {
let mut bar = Bar1 { x: Foo {} };
let y = bar.f(); // (1) 'bar' is borrowed by 'y'
let z = bar.f(); // error (as expected) : cannot borrow `bar` as mutable more
// than once at a time [E0499]
}
fn f2() {
let mut bar = Bar1 { x: Foo {} };
bar.f(); // (2) 'bar' is not borrowed after the call
let z = bar.f(); // ok (as expected)
}
}
那个不行的:mod case2 {
struct Foo {}
struct Bar2<'b> {
x: &'b Foo,
}
impl<'b> Bar2<'b> {
fn f(&'b mut self) -> &'b Foo {
self.x
}
}
fn f4() {
let foo = Foo {};
let mut bar2 = Bar2 { x: &foo };
bar2.f(); // (3) 'bar2' is borrowed as mutable, but who borrowed it?
let z = bar2.f(); // error: cannot borrow `bar2` as mutable more than once at a time [E0499]
}
}
我希望我能像情况1那样两次调用Bar2::f
,而不会惹恼编译器。
问题在注释(3)中:是谁借走了bar2
,而没有任何影响?
这是我的理解:
在情况1中,
f2
调用:'a
生命周期参数是接收到的&Foo
值的生命周期,因此当没有任何影响时,此生命周期为空,并且在Bar1::f
调用后bar
没有被借用;在情况2中,
bar2
借用foo
(不可变),因此Bar2
结构体中的生命周期参数'b
是foo
引用的生命周期,它在f4
函数体末尾结束。调用Bar2::f
将借用bar2
,并持续到f4
函数体末尾。
但问题仍然是:是谁借走了bar2
?可能是Bar2::f
吗?Bar2::f
如何在调用后保持借用所有权?我漏掉了什么?
我使用的是Rust 1.14.0-nightly (86affcdf6 2016-09-28) on x86_64-pc-windows-msvc。