返回包含引用的结果时,不能一次多次借用“*self”作为可变对象

Cannot borrow `*self` as mutable more than once at a time when returning a Result containing a reference

为什么以下无效,我应该怎么做才能使其有效?

struct Foo;

impl Foo {
    fn mutable1(&mut self) -> Result<(), &str> {
        Ok(())
    }

    fn mutable2(&mut self) -> Result<(), &str> {
        self.mutable1()?;
        self.mutable1()?;
        Ok(())
    }
}

此代码产生:

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

已经有很多问题出现了同样的错误,但我不能用它们来解决这个问题,因为 ? 提供的隐式 return 的存在导致了问题,而没有 ? 代码编译成功,但有警告。

Playground

这与 中讨论的问题相同。通过 lifetime elision&str 的生命周期与 &self 的生命周期相关联。编译器不知道在返回 Ok 的情况下不会使用借用。它过于保守并且不允许此代码。这是当前借用检查器实现的一个限制。

如果您确实需要 Err 变体的生命周期与 Foo 实例的生命周期相关联,那么在安全 Rust 中没有什么可做的(不安全 Rust 是 ).但是,在您的情况下,您的 &str 似乎不太可能与 self 的生命周期相关联,因此您可以使用明确的生命周期来避免该问题。例如,&'static str 是一种常见的基本错误类型:

impl Foo {
    fn mutable1(&mut self) -> Result<(), &'static str> {
        Ok(())
    }

    fn mutable2(&mut self) -> Result<(), &'static str> {
        self.mutable1()?;
        self.mutable1()?;
        Ok(())
    }
}

as it's the presence of the implicit return provided by ?

不是,因为使用 explicit returns 的相同代码有同样的问题:

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(())
}
error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/lib.rs:12:25
   |
8  |     fn mutable2(&mut self) -> Result<(), &str> {
   |                 - let's call the lifetime of this reference `'1`
9  |         if let Err(e) = self.mutable1() {
   |                         ---- first mutable borrow occurs here
10 |             return Err(e);
   |                    ------ returning this value requires that `*self` is borrowed for `'1`
11 |         }
12 |         if let Err(e) = self.mutable1() {
   |                         ^^^^ second mutable borrow occurs here