循环中的可变借用

14

我试图在循环内获取可变借用,但无法使其正常工作。我尝试了所有可能的保护机制、原始指针和其他所有方法。


struct Test<'a> {
    a: &'a str,
}

impl<'a> Test<'a> {
    pub fn new() -> Self {
        Test { a: &mut "test" }
    }

    pub fn dostuff(&'a mut self) {
        self.a = "test";
    }

    pub fn fixme(&'a mut self) {
        let mut i = 0;
        while i < 10 {
            self.dostuff();
            i += 1;
        }
    }
}

fn main() {
    let mut test = Test::new();
    test.fixme();
}
error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/main.rs:19:13
   |
19 |             self.dostuff();
   |             ^^^^ mutable borrow starts here in previous iteration of loop
...
22 |     }
   |     - mutable borrow ends here

Rust Playground 示例代码

我无法弄清楚如何解决这个问题。 我需要修复程序并仍保持函数签名不变。 我的代码更加复杂,但是这段代码将其简化到最少。

这里是我正在尝试解决的完整代码


我需要修复,同时保持函数不变。如果我们不能改变任何东西,就无法修复任何东西。 - Shepmaster
你有使用 &str 而不是 String 的充分理由吗?如果 Test 拥有该字符串,请使用拥有所有权的类型。 - Boiethios
我已经添加了我遇到问题的实际代码,并将其推送到git存储库。Playground gist只是错误本身的示例。 - Chronium
1个回答

16
当你编写fn dostuff(&'a mut self)时,你强制引用self的寿命至少与生命周期'a一样长。但这个'a与你在Test结构的定义中使用的是相同的。这意味着dostuff的调用者必须将self借给test的整个生命周期。一旦dostuff()被调用一次,self就被借用了,而这个借用直到test被丢弃才结束。根据定义,你只能调用该函数一次,所以你不能在循环中调用它。

我需要修复后仍保持函数签名不变

因此,你现在应该理解这是一个不可能的要求。你可以将函数签名保持不变,或者你可以在循环中调用它,但不能两者兼得。

2
我有一个类似的问题,但是我没有像 OP 那样严格的函数签名要求:我的选择是什么? - CrepeGoat
你可以为函数doStuff()添加一个不同的生命周期。这样编译器就知道可变引用self只需要在函数调用期间存在。pub fn dostuff<'b>(&'b mut self) { self.a = "test"; } - Thore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接