如果我们运行它,那么我们会正确地得到错误“无法分配给不可变字段a.x
”。
如果我们删除这两个//
注释,并注释掉这个坏行,那么我们会得到错误“无法分配给&
引用中的数据”。这是有道理的,因为&mut
不提供内部可变性。我们可以&A
自由地重新借用,所以这不能提供可变访问,ala&&mut
是&&
.
如果我们同时删除//
注释和/* */
注释,那么整个事情都会编译,允许违反我们的不变量的坏行a.x
永远不能指向其他任何东西。
pub struct A<'a> {
pub x: &'a mut [u8; 3],
}
fn main() {
let y = &mut [7u8; 3];
let /*mut*/ a = A { x: &mut [0u8; 3] };
a.x[0] = 3;
a.x = y; //// This must be prevented!
{
// let b = &/*mut*/ a;
// b.x[1] = 2;
}
println!("{:?}", a.x);
}
应该如何维护这个x
不可更改的不变量?我们可以在提供公共解引用方法的同时将字段设为私有,除了A
不可接受的为 in 编写构造函数。
我们可以通过创建A
一个包装器的私有成员来避免令人讨厌的构造函数,该包装器struct AA(A)
本身承载公共解引用方法。现在AA
需要一个简单的构造函数,但它不需要所有字段的参数A
,不影响执行顺序等。如果我们需要为两者实现一些特征,这将变得很A
痛苦AA
。
然而,另一种方法是通过使用内部可变性Cell<A>
,使用Cell::replace
,然后再放回去。这听起来很有问题,但表明存在更多解决方案。
任何更清洁的方法?