在范围内存在 mut 引用时进行引用

Referencing while a mut reference exists in scope

我有这个代码:

fn main() {
    let mut s = "My string".to_string();
    let ref1 = &mut s;
    // let ref2 = &s; //Doesn't compile
    let ref3 = &*ref1; //*ref1 is s. So &*ref1 is &s => compiles
}

let ref2 = &s; 无法编译,因为作用域中已经有一个 mut 引用。但是,let ref3 = &*ref1 确实可以编译。

据我了解,*ref1 应该 return s。所以 &*ref1 应该是 &s 并且它出于某种原因编译。

为什么会这样?

首先,Rusts借用的工作原理如下: 您有 一个可变 引用或 n 个不可变 引用。

  • let ref1 = &mut s; 创建对 s.

  • 的可变引用
  • let ref2 = &s; 尝试创建对 s 的不可变引用。 这显然是不可能的。我们已经有了一个可变引用 到 s.

let ref3 = &*ref1; 创建对 *ref1

的不可变引用

如果您尝试将 asgn 分配给 ref1 afterwords 它不会工作:

*ref1 = "Other string".to_string();

结果:

error: cannot assign to '*ref1' because it is borrowed [E0506]

请记住,借用是有范围的。请参阅以下示例:Playground

fn main() {
    let mut s = "My string".to_string();
    {
        let ref1 = &mut s;
        //println!("{}", s); //Does not compile. s is borrowed as mutable
        {
            let ref3 = &(*ref1); //*ref1 is now borrowed as immutable.
            println!("{}", ref1); //We can read it
            //*ref1 = "Other string".to_string();//but not assign to it
            println!("{}", ref3);
        }
        //ref3 is now out of scope and so is the immutable borrow
        *ref1 = "Other string".to_string();//We can now assign to *ref1
        println!("{}", ref1);
    }
    //Now that the mutable borrow from ref1 is out of scope, we can read s again
    println!("{}", s);
}