Code Fix

初級

E0596: cannot borrow as mutable の原因と直し方

mutを付けずに宣言した変数を、&mutで可変参照として渡そうとするとE0596エラーになります。値を変更する関数に渡す変数は、宣言時からmutにしておく必要があります。

エラーメッセージの読み方

error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
E0596
エラーコード — `rustc --explain E0596` で詳しい説明が見られます
cannot borrow `x` as mutable, as it is not declared as mutable
詳細メッセージ — 何が問題だったか

このエラーが出る典型パターン

パターン1

 1  fn increment(n: &mut i32) {
 2      *n += 1;
 3  }
 4  
 5  fn main() {
 6      let       x = 5;
               ^
 7      increment(&mut x);
 8      println!("{}", x);
 9  }
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable

&mutで可変参照として渡すには、渡す側の変数自体がmutで宣言されている必要があります。

直し方: (空) を mut にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  fn double_it(n: &mut i32) {
 2      *n *= 2;
 3  }
 4  
 5  fn main() {
 6      let       value = 10;
               ^
 7      double_it(&mut value);
 8      println!("{}", value);
 9  }
error[E0596]: cannot borrow `value` as mutable, as it is not declared as mutable

呼び出し側で&mutを付けても、束縛自体がmutでなければ可変借用は許されません。

直し方: (空) を mut にします。

この問題を解いてみる →

パターン3

 1  fn add_bonus(n: &mut i32) {
 2      *n += 10;
 3  }
 4  
 5  fn main() {
 6      let       score = 80;
               ^
 7      add_bonus(&mut score);
 8      println!("{}", score);
 9  }
error[E0596]: cannot borrow `score` as mutable, as it is not declared as mutable

可変で借用できるかどうかは、あくまで元の変数の宣言時の状態で決まります。

直し方: (空) を mut にします。

この問題を解いてみる →

パターン4

 1  fn reset(n: &mut i32) {
 2      *n = 0;
 3  }
 4  
 5  fn main() {
 6      let       counter = 5;
               ^
 7      reset(&mut counter);
 8      println!("{}", counter);
 9  }
error[E0596]: cannot borrow `counter` as mutable, as it is not declared as mutable

関数側の引数型を&mutにするだけでなく、呼び出し側の変数もmutにする必要があります。

直し方: (空) を mut にします。

この問題を解いてみる →

パターン5

 1  fn halve(n: &mut i32) {
 2      *n /= 2;
 3  }
 4  
 5  fn main() {
 6      let       amount = 40;
               ^
 7      halve(&mut amount);
 8      println!("{}", amount);
 9  }
error[E0596]: cannot borrow `amount` as mutable, as it is not declared as mutable

mutを付け忘れると、値を変更する関数に渡す時点でコンパイルエラーになります。

直し方: (空) を mut にします。

この問題を解いてみる →

よくある誤解

「&mutを付けて渡す側で可変にできるはず」という思い込みは誤りです。可変で借用できるかどうかは、渡す側の変数自体がmutで宣言されているかどうかで決まります。

実務での勘所

Rustにおける可変性は、値の型に付いている性質ではなく、変数の束縛(バインディング)に付いている性質です。まったく同じString型の値でも、let s = ...と束縛すれば不変、let mut s = ...と束縛すれば可変になり、この違いは型そのものではなく「その変数名でどう受け取ったか」だけで決まります。&mutで可変に借用できるかどうかは、値の型を見ても分からず、借用元の変数がmutで宣言されているかどうかだけで判定されます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)