首页 文章

对自我的可变借用不会变为不可变

提问于
浏览
9

此代码未通过可怕的借用检查程序(playground):

struct Data {
    a: i32,
    b: i32,
    c: i32,
}

impl Data {
    fn reference_to_a(&mut self) -> &i32 {
        self.c = 1;
        &self.a
    }
    fn get_b(&self) -> i32 {
        self.b
    }
}

fn main() {
    let mut dat = Data{ a: 1, b: 2, c: 3 };
    let aref = dat.reference_to_a();
    println!("{}", dat.get_b());
}

错误:

error[E0502]: cannot borrow `dat` as immutable because it is also borrowed as mutable
  --> <anon>:19:20
   |
18 |     let aref = dat.reference_to_a();
   |                --- mutable borrow occurs here
19 |     println!("{}", dat.get_b());
   |                    ^^^ immutable borrow occurs here
20 | }
   | - mutable borrow ends here

有人可以解释为什么这是?当 reference_to_a() 返回时,我会认为 dat 的可变借用被转换为不可变的,因为该函数只返回一个不可变引用 . 借用检查员还不够聪明吗?这是计划好的吗?有办法解决吗?

1 回答

  • 3

    生命期与参考是否可变是分开的 . 完成代码:

    fn reference_to_a(&mut self) -> &i32
    

    尽管生命周期已被省略,但这相当于:

    fn reference_to_a<'a>(&'a mut self) -> &'a i32
    

    即输入和输出寿命是相同的 . 这是将生命周期分配给这样一个函数的唯一方法(除非它返回了对全局数据的 &'static 引用),因为你无法从零构成输出生命周期 .

    这意味着如果通过将返回值保存在变量中来保持返回值,那么您也将保持 &mut self 活着 .

    另一种思考方式是 &i32&mut self 的子借位,因此只有在到期之前才有效 .

    正如@aSpex指出的那样,这是covered in the nomicon .

相关问题