循环中的可变借用

Posted

技术标签:

【中文标题】循环中的可变借用【英文标题】:Mutable borrow in a loop 【发布时间】:2018-10-11 05:22:28 【问题描述】:

我有以下代码:

struct Baz 
    x: usize,
    y: usize,


struct Bar 
    baz: Baz,


impl Bar 
    fn get_baz_mut(&mut self) -> &mut Baz 
        &mut self.baz
    


struct Foo 
    bar: Bar,


impl Foo 
    fn foo(&mut self) -> Option<&mut Baz> 
        for i in 0..4 
            let baz = self.bar.get_baz_mut();
            if baz.x == 0 
                return Some(baz);
            
        
        None
    

Rust Playground

编译失败:

error[E0499]: cannot borrow `self.bar` as mutable more than once at a time
  --> src/main.rs:23:23
   |
23 |             let baz = self.bar.get_baz_mut();
   |                       ^^^^^^^^ mutable borrow starts here in previous iteration of loop
...
29 |     
   |     - mutable borrow ends here

但是,如果我从 Foo::foo 返回 Some(baz.x)(并将返回类型更改为 Option&lt;usize&gt;),则代码会编译。这让我相信问题不在于循环,即使编译器似乎表明了这一点。更具体地说,我相信本地可变引用 baz 将在循环的下一次迭代中超出范围,导致这不是问题。以上代码的生命周期问题是什么?

以下问题类似:

Mutable borrow in loop Linking the lifetimes of self and a reference in method Cannot borrow as mutable more than once at a time in one code - but can in another very similar

但是,它们处理显式声明的生命周期(特别是这些显式生命周期是答案的一部分)。我的代码省略了这些生命周期,因此删除它们是不可行的。

【问题讨论】:

我很惊讶我没有找到这个问题的副本,但我通常不擅长在 SO 中搜索问题。可能是因为您的示例不是很地道,可能太简单而无法表达真正的问题。 【参考方案1】:

它不起作用,因为返回借用的值会将借用扩展到函数的末尾。

有关一些有用的详细信息,请参阅here。

这适用于带有 1.27 夜间版本的non-lexical lifetimes:

#![feature(nll)]

struct Baz 
    x: usize,
    y: usize,


// ...

非词法生命周期 RFC 解释了生命周期的实际工作:

但是,当您的引用跨越多个语句时,就会出现问题。在这种情况下,编译器要求生命周期是包含两个语句的最里面的表达式(通常是一个块),并且通常比实际需要或期望的要大得多

rustc nightly 1.28

作为pointed out by @pnkfelix,从 nightly 1.28 开始的非词法生命周期实现不再编译上述代码。

不过有a long-term plan to (re)-enable a more powerful NLL analysis。

【讨论】:

当前版本的 NLL 似乎不接受给定的确切代码;见讨论here at rust-lang/rust#43234

以上是关于循环中的可变借用的主要内容,如果未能解决你的问题,请参考以下文章

可变地借用一个结构字段,同时在闭包中借用另一个

为啥 &mut self 允许借用 struct 成员,但不允许将 self 借用到不可变方法?

函数中的可变循环数(python)

不能将不可变的'Box'内容借用为可变的

当前范围错误中的重复声明;两个循环具有相同的变量,可变范围

Java学习基础的第四天 for循环,Java语法中的方法,方法的重载,可变参数,递归,数组