为了彻底弄明白所有权和引用的约束,再试试连续引用的一些特殊情况。结构体:
#[derive(Debug)]
struct Point {
x: Box<i32>,
y: Box<i32>,
z: i32,
}
1、先看第一种一般情况,连续不可变引用,可以编译运行:
fn main() {
let a = Point {
x: Box::new(3),
y: Box::new(4),
z: 5,
};
let b = &a;
let c = &b;
// c.z += 5;
println!("{:?}", c);
println!("{:?}", b);
println!("{:?}", a);
}
2、一般情况之二,连续可变引用,可以修改被引用对象的值:
let mut a = Point {
x: Box::new(3),
y: Box::new(4),
z: 5,
};
let mut b = &mut a;
let c = &mut b;
c.z += 5;
println!("{:?}", c);
println!("{:?}", b);
println!("{:?}", a);
最终其实是a.z的值被修改。输出:
Point { x: 3, y: 4, z: 10 }
Point { x: 3, y: 4, z: 10 }
Point { x: 3, y: 4, z: 10 }
3、特殊情况之一,不可变引用的可变引用,是否允许,以及能否改变目标成员的值?下列代码中,b为a的不可变引用,c为b的可变引用。
let a = Point {
x: Box::new(3),
y: Box::new(4),
z: 5,
};
let mut b = &a;
let c = &mut b;
c.z += 5; // Error! cannot assign to `c.z` which is behind a `&` reference
编译错误,不允许这样修改!如果把“ c.z += 5;”这行注释掉,则可以编译,看来rust允许这样连续借用,但在这种情况下不允许修改目标值。
4、特殊情况之二:可变引用的不可变引用。b为a的可变引用,c为b的不可变引用。
let mut a = Point {
x: Box::new(3),
y: Box::new(4),
z: 5,
};
let b = &mut a;
let c = &b;
c.z += 5; // Error! `c` is a `&` reference, so the data it refers to cannot be written
同样报错!将 “c.z += 5;”注释掉以后,可以编译运行,也说明rust允许这样连续引用,但不允许修改值。