可変参照がある間は、他の参照は許されない
from 借用における2つの制約
以下のいずれかの状態しかない
参照されていない
不変参照のみが1個以上ある
可変参照のみが1個だけある
race condition的なやつ
値が共有されている間は、値の変更を許さない
反例
可変参照があるのに、不変参照もしている
この制約がないと、不変参照を通じて読み取っている最中にデータが書き換えられてしまい、予期しない動作を引き起こす可能性がある。
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
/mrsekut-book-4065301955/081 (3.4.2 可変参照としての借用)
状態遷移図で解説してる
/mrsekut-book-4295015296/391 (23.5 「別名で変更されたオブジェクトの使用」エラーを防ぐ方法)
/mrsekut-book-4297105594/291 (7-8 参照のライフタイムと借用規則)