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

时间:2016-06-09 20:31:51

标签: rust borrow-checker

我有这段代码:

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应该返回s。所以&*ref1应该是&s并且由于某种原因而编译。

为什么会这样?

1 个答案:

答案 0 :(得分:1)

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

  • let ref1 = &mut s;创建了对s的可变引用。

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

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

的不可变引用

如果您尝试使用ref1后缀,则无效:

*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);
}