Rust中引用规则为

对于两个不同的引用而言,不可变引用实现了Copy,可变引用没有实现。

引用的重借用

let mut a =1;
let b=&mut a;
let c=b;   //let c:&mut i32=b
println!("{}", b);

上面的代码会报错,原因是由于可变引用b是move的,所以第三行会转移所有权到c,因此无法通过编译。

但是倘若把第三行改为let c:&mut i32=b,代码就可以正常运行,这里发生了reborrow。

let c:&mut i32=b等价于更具体的let c:&mut i32=&mut (*b)

上述代码也可以改为let c:&i32=b,这里发生了reborrow和类型的coercion,由于存在&mut T到&T的coercion,因此代码可以正常运行。

reborrow与原引用的规则与引用和被引用对象的规则相似。

reborrow不仅在上述的例子中存在,在函数调用,结构创建等地方都会存在,由此可知当接收变量有明确的引用类型时会发生reborrow。

struct A<'a>(&'a mut i32);
let mut a =1;
let b=&mut a;
let c = A(b);
println!("{}", b);

综上所述,上述代码可以正常运行。

但是这里更改代码,将第一行A的定义改为struct A<T>(T),这里就会发生b的move行为,编译失败。

对元祖以及复合结构体的引用的成员取引用也是reborrow的一种。

struct A(i32,i32);
impl A {
    fn foo(&mut self) {
        let a=&self.0;
        self.bar();
        a;
    }
    fn bar(&mut self) {}
}

上述代码会报错。