Rust: cannot borrow as mutable
Rustで可変借用のルールに違反した際のエラー原因と解決策
概要
Rustの借用規則に違反し、同時に複数の可変参照または可変と不変の参照が存在する場合のエラーです。
エラーメッセージ
``` error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable –> src/main.rs:4:5 | 3 | let r1 = &x; | – immutable borrow occurs here 4 | let r2 = &mut x; | ^^^^^^ mutable borrow occurs here 5 | println!("{}", r1); | – immutable borrow later used here ```
原因
- 同時の可変・不変借用: 同じスコープで両方の参照
- 複数の可変借用: &mut が2つ以上
- 借用中の所有権移動: 参照が有効な間に値を移動
- 構造体フィールドの部分借用: 同一構造体の異なるフィールド
解決策
1. スコープを分離
```rust let mut x = 5;
// 悪い例 let r1 = &x; let r2 = &mut x; // エラー println!("{}", r1);
// 良い例 { let r1 = &x; println!("{}", r1); } // r1 のスコープ終了 let r2 = &mut x; // OK ```
2. 借用を使い終わってから変更
```rust let mut vec = vec![1, 2, 3];
// 悪い例 let first = &vec[0]; vec.push(4); // エラー: vec は不変借用中 println!("{}", first);
// 良い例 let first = vec[0]; // コピー vec.push(4); // OK println!("{}", first); ```
3. RefCellで内部可変性
```rust use std::cell::RefCell;
let data = RefCell::new(vec![1, 2, 3]);
// 実行時に借用チェック let borrowed = data.borrow(); println!("{:?}", borrowed); drop(borrowed); // 明示的に借用を終了
data.borrow_mut().push(4); // OK ```
4. 構造体の部分借用
```rust struct Data { field1: String, field2: i32, }
let mut data = Data { field1: String::new(), field2: 0 };
// 異なるフィールドなら同時借用可能 let f1 = &mut data.field1; let f2 = &mut data.field2; // OK(Rustが分析可能) ```
5. split_at_mutで分割借用
```rust let mut arr = [1, 2, 3, 4, 5];
// 悪い例 let a = &mut arr[0]; let b = &mut arr[1]; // エラー
// 良い例 let (left, right) = arr.split_at_mut(1); let a = &mut left[0]; let b = &mut right[0]; // OK ```
よくある間違い
- イテレータ中にコレクションを変更
- self を複数回可変借用
- ライフタイムの誤解
関連エラー
関連エラー
Rust の他のエラー
この記事は役に立ちましたか?