可変参照がある間は、他の参照は許されない
以下のいずれかの状態しかない
参照されていない
不変参照のみが1個以上ある
可変参照のみが1個だけある
値が共有されている間は、値の変更を許さない
反例
可変参照があるのに、不変参照もしている
この制約がないと、不変参照を通じて読み取っている最中にデータが書き換えられてしまい、予期しない動作を引き起こす可能性がある。
https://gyazo.com/95f6ff6945b72f8a7b67d930db284587
code:rust
fn main() {
let mut x = 10;
let r1 = &x; // 不変参照
let r2 = &mut x; // 可変参照 ← ここでエラー
println!("r1: {}", r1);
}
code:error
errorE0502: cannot borrow x as mutable because it is also borrowed as immutable --> src/main.rs:6:14
|
5 | let r1 = &x; // 不変参照
| -- immutable borrow occurs here
6 | let r2 = &mut x; // 可変参照
| ^^^^^^ mutable borrow occurs here
7 | println!("r1: {}", r1);
| -- immutable borrow later used here
可変参照が複数ある
複数の可変参照が許されると、データの変更が競合し、未定義動作を引き起こす可能性がある。
この制約があることで「データの一貫性」を保証し、予測不能な動作を防ぐことができる。
code:rust
fn main() {
let mut x = 10;
let r1 = &mut x; // 可変参照1
let r2 = &mut x; // 可変参照2 ← ここでエラー
println!("r1: {}", r1);
}
code:error
errorE0499: cannot borrow x as mutable more than once at a time --> src/main.rs:6:14
|
5 | let r1 = &mut x; // 可変参照1
| ------ first mutable borrow occurs here
6 | let r2 = &mut x; // 可変参照2
| ^^^^^^ second mutable borrow occurs here
7 | println!("r1: {}", r1);
| -- first borrow later used here
状態遷移図で解説してる