cYr*_*rus 5 rust borrow-checker
为什么以下无效,我应该怎么做才能使其工作?
struct Foo;
impl Foo {
fn mutable1(&mut self) -> Result<(), &str> {
Ok(())
}
fn mutable2(&mut self) -> Result<(), &str> {
self.mutable1()?;
self.mutable1()?;
Ok(())
}
}
Run Code Online (Sandbox Code Playgroud)
此代码产生:
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/lib.rs:10:9
|
8 | fn mutable2(&mut self) -> Result<(), &str> {
| - let's call the lifetime of this reference `'1`
9 | self.mutable1()?;
| ---- - returning this value requires that `*self` is borrowed for `'1`
| |
| first mutable borrow occurs here
10 | self.mutable1()?;
| ^^^^ second mutable borrow occurs here
Run Code Online (Sandbox Code Playgroud)
有很多问题已经有相同的错误,但我不能用它们来解决这个问题,因为它?
是导致问题的隐式返回的存在,没有?
代码成功编译,但有警告。
这与从 HashMap 或 Vec 返回引用导致借用持续超出其所在范围中讨论的问题相同?. 通过生命周期省略, 的生命周期&str
与 的生命周期相关&self
。编译器不知道在Ok
返回an 的情况下不会使用借用。它过于保守并且不允许使用此代码。这是当前借用检查器实现的限制。
如果您确实需要将Err
变体的生命周期与Foo
实例的生命周期相关联,那么在安全 Rust 中没有什么可做的(不安全 Rust 是另一回事)。但是,在您的情况下,您似乎不太可能&str
与 的生命周期相关联self
,因此您可以使用显式生命周期来避免该问题。例如,a&'static str
是常见的基本错误类型:
impl Foo {
fn mutable1(&mut self) -> Result<(), &'static str> {
Ok(())
}
fn mutable2(&mut self) -> Result<(), &'static str> {
self.mutable1()?;
self.mutable1()?;
Ok(())
}
}
Run Code Online (Sandbox Code Playgroud)
因为它是由提供的隐式回报的存在
?
并非如此,因为具有显式返回的相同代码具有相同的问题:
fn mutable2(&mut self) -> Result<(), &str> {
if let Err(e) = self.mutable1() {
return Err(e);
}
if let Err(e) = self.mutable1() {
return Err(e);
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
impl Foo {
fn mutable1(&mut self) -> Result<(), &'static str> {
Ok(())
}
fn mutable2(&mut self) -> Result<(), &'static str> {
self.mutable1()?;
self.mutable1()?;
Ok(())
}
}
Run Code Online (Sandbox Code Playgroud)