返回包含引用的结果时,一次不能多次借用* self可变

问题描述 投票:0回答:1

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

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

[已经有很多问题具有相同的错误,但是我不能用它们来解决这个问题,因为是由?提供的隐式返回的存在导致了问题,没有?的代码就可以成功编译,但是会出现警告。

Playground

rust borrow-checker
1个回答
0
投票

这与Returning a reference from a HashMap or Vec causes a borrow to last beyond the scope it's in?中讨论的问题相同。通过生存期省略&str的生存期与&self的生存期相关。编译器不知道在返回Ok的情况下不会使用借用。过于保守,不允许使用此代码。这是当前借阅检查器实现的限制。

如果您确实需要将Err变量的生存期与Foo实例的生存期相关联,那么在安全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(())
    }
}

因为它是?提供的隐式返回的存在>

并非如此,因为带有explicit

的相同代码会返回相同的问题:
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

© www.soinside.com 2019 - 2024. All rights reserved.