thisを実行すると、「不可能なフィールドa.x
に割り当てられません」というエラーが正しく表示されます。内部の可変性とデータの隠蔽性の違いがあり、変更可能な借用の参照を固定している場合
2つのコメントを削除し、この悪い行をコメントアウトすると、「&
の参照にデータを割り当てることができません」というエラーが表示されます。 &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
のコンストラクタを書くことが容認できないことを除いて、パブリックの参照解除メソッドを提供しながらフィールドをプライベートにすることができます。
我々はA
自体がパブリックデリファレンス・メソッドをホストするラッパーstruct AA(A)
のプライベートメンバにすることによって不快なコンストラクタを回避することができます。今度はAA
は簡単なコンストラクタを必要としますが、A
のすべてのフィールドに引数を必要とせず、実行順序などに影響を与えません。A
とAA
の両方に実装されたいくつかの特性が必要な場合、
Cell<A>
で作業し、Cell::replace
でアクセスして後で戻すことで、内部の変更を使用する方法もあります。これは非常に問題が多いようですが、より多くの解決策が存在することを示しています。
どんなクリーナーアプローチですか?
もう1つの方法は、配列の中で 'Cell'を使うことです。それを試しましたか? –