Rust中借用和隐式重借用的区别?

新手上路,请多包涵

rust新手,看到隐式重借用,有些不解,望能够帮忙解答。

下面代码都是重复可变引用,但为什么通过隐式重借用方式,就可以实现多个可变引用?rust不是明确说同一时间只能有一个可变引用吗?

// err 能够理解,rust明确不能有两个可变引用。
fn compile_err() {
    let mut s = String::from("hello");

    let r1 = &mut s;
    {
        let r2 = &mut s;
        dbg!(r2);
    }
    dbg!(r1);  // compile ERR
}

// 但通过隐式重借用,为啥就可以,(*r1) 解应用的最终对应的不还是 s?
fn compile_ok() {
    let mut s = String::from("hello");

    let r1 = &mut s;
    {
        let r2 = &mut (*r1);
        dbg!(r2);
    }
    dbg!(r1);  // compile OK
}
阅读 943
1 个回答

borrow-checker 是一个编译期的检查。在实际的程序中,在编译期看到 *r1 的时候,通常是很难确定其实际对象是什么的。(虽然在你的这个简单的程序中可以比较容易确定,但是这种情况在实际的程序中会是比较少见的。)所以 borrow-check 不会把 *r1s 当成同一个对象进行检查。

同时,在 r2 存在时,r1 已经不能使用了。因为使用 r1, 通常就意味着要对 *r1 进行 borrow 。borrow-checker 会在 r2 存在时阻止再次对 *r1 进行 borrow。
比如:

        let mut s = String::from("s");
        let r1 = &mut s;
        {
            let r2 = &mut (*r1);
            let l = r1.len(); // ERROR
            r2.push('2');
            r1.push('3'); // ERROR
            println!("{}", r2);
        }
        println!("{}", r1);

因为,此处的两个对 r1 的使用,分别需要对 *r1 进行 borrow / mutable borrow 。而 r2 的存在使得对 *r1 进行此类操作不可能。

所以,同时还是只有一个“可用的”对 s 的 mutable borrow。

    let r1 = &mut s;
    {
        let r2 = &mut s;
        dbg!(r2);
    }
    dbg!(r1);

不会有这个效果。如果 let r1 = &mut s 合法,那么 r1r2 将是同时可用的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进