在这里,我有一个结构体
Bar
,其中引用了Foo
。我最近收到一个与此模式匹配的错误,想尝试创建一个可重现的示例。
struct Bar<'a> {
foo: &'a Foo,
}
struct Foo;
impl Foo {
fn borrow_mut(&mut self) {
unimplemented!()
}
fn create_option_bar(&self) -> Option<Bar> {
unimplemented!()
}
fn create_bar(&mut self) -> Bar {
let option_bar = self.create_option_bar();
if option_bar.is_some() {
return option_bar.unwrap();
}
self.borrow_mut();
unimplemented!()
}
}
所以...这不编译 但是,如果我做这样的事情
fn can_guarantee_option_bar_will_be_some() -> bool {
unimplemented!()
}
impl Foo {
// ... same as before
fn create_bar(&mut self) -> Bar {
if can_guarantee_option_bar_will_be_some() {
return self.create_option_bar().unwrap();
}
self.borrow_mut();
unimplemented!()
}
}
效果很好! 现在……这到底是怎么回事?这两个不是在做同样的事情吗?
我想知道
error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
--> src/main.rs:44:9
|
37 | fn create_bar(&mut self) -> Bar {
| - let's call the lifetime of this reference `'1`
...
41 | if let Some(bar) = self.create_option_bar() {
| ------------------------ immutable borrow occurs here
42 | return bar;
| --- returning this value requires that `*self` is borrowed for `'1`
43 | }
44 | self.borrow_mut();
| ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
这里是完整的错误^
您的代码使用实验性 polonius 借用检查器构建:
RUSTFLAGS="-Zpolonius" cargo +nightly build
这是当前借用检查器的已知误报。有一个箱子可以解决这个问题,称为
polonius_the_crab
。可以在那里找到有关该问题的更多信息。
以下是使用此板条箱修复它的方法:
use ::polonius_the_crab::prelude::*;
struct Bar<'a> {
foo: &'a Foo,
}
struct Foo;
impl Foo {
fn borrow_mut(&mut self) {
unimplemented!()
}
fn create_option_bar(&self) -> Option<Bar> {
unimplemented!()
}
fn create_bar(&mut self) -> Bar {
let mut this = self;
polonius!(|this| -> Bar<'polonius> {
let option_bar = this.create_option_bar();
if option_bar.is_some() {
polonius_return!(option_bar.unwrap());
}
});
this.borrow_mut();
unimplemented!()
}
}
除此之外,还有几种方法可以解决这个问题:
很抱歉没有直接的解决方案。