Я сражаюсь с заемщиком. У меня есть два похожих фрагмента кода, один из которых работает, как я ожидаю, а другой нет.
Тот, который работает так, как я ожидаю:
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]
}
}
Я надеялся, что дважды позвоню Bar2::f
, не раздражая компилятор, как в случае 1.
Вопрос находится в комментарии (3): кто заимствовал bar2
, тогда как нет никакой аффектации?
Вот что я понимаю:
-
В случае 1,
f2
вызов: параметр lifetime'a
является одним из принимающего значения&Foo
, поэтому это время жизни пуст, если нет аффектации, аbar
не заимствовано после вызоваBar1::f
; -
В случае 2,
bar2
занимаетfoo
(как неизменяемое), поэтому параметр lifetime'b
вbar2
struct - это ресурсfoo
, который заканчивается в концеf4
корпус. ВызовBar2::f
занимаетbar2
для этого времени жизни, а именно до концаf4
.
Но вопрос по-прежнему: кто заимствовал bar2
? Может ли это быть Bar2::f
? Как Bar2::f
будет удерживать заемную собственность после разговора? Что мне здесь не хватает?
Я использую Rust 1.14.0-nightly (86affcdf6 2016-09-28) на x86_64-pc-windows-msvc.