Code Fix

初級

called `Option::unwrap()` on a `None` value パニックの原因と直し方

Option<T>型の値がNoneのときにunwrap()を呼び出すと、パニックが発生してプログラムが異常終了します。findやgetなど、見つからない可能性のある操作の戻り値はOptionになります。

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

thread 'main' panicked at main.rs:4:26:
main.rs
ファイル名
4
行番号 — 実際にクラッシュした行
26
列番号
panicked
パニック — 実行時に回復不能な状態になったことを示します。tryやResultで捕まえない限り、そのままプロセスが終了します
called `Option::unwrap()` on a `None` value
詳細メッセージ — どの値が問題だったか

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

パターン1

 1  fn main() {
 2      let users = vec!["taro", "hanako"];
 3      let found = users.iter().find(|&&u| u == "jiro  ");
                                                     ^
 4      println!("{}", found.unwrap());
 5  }
thread 'main' panicked at main.rs:4:26: called `Option::unwrap()` on a `None` value

findは条件に一致する要素が無いとNoneを返します。Noneに対してunwrap()を呼ぶとパニックします。

直し方: jirohanako にします。

この問題を解いてみる →

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

パターン2

 1  fn main() {
 2      let fruits = vec!["apple", "banana", "grape"];
 3      let found = fruits.iter().find(|&&f| f == "orange");
                                                      ^
 4      println!("{}", found.unwrap());
 5  }
thread 'main' panicked at main.rs:4:26: called `Option::unwrap()` on a `None` value

見つかるかどうか分からない検索結果をそのままunwrap()すると、見つからなかった場合にパニックします。

直し方: orangebanana にします。

この問題を解いてみる →

パターン3

 1  fn main() {
 2      let cities = vec!["tokyo", "osaka"];
 3      let found = cities.iter().find(|&&c| c == "kyoto");
                                                     ^
 4      println!("{}", found.unwrap());
 5  }
thread 'main' panicked at main.rs:4:26: called `Option::unwrap()` on a `None` value

unwrap()は中身がSomeかどうかを確認せずに取り出そうとする、安全性を犠牲にした操作です。

直し方: kyotoosaka にします。

この問題を解いてみる →

パターン4

 1  fn main() {
 2      let colors = vec!["red", "blue", "green"];
 3      let found = colors.iter().find(|&&c| c == "yellow");
                                                      ^
 4      println!("{}", found.unwrap());
 5  }
thread 'main' panicked at main.rs:4:26: called `Option::unwrap()` on a `None` value

存在確認をせずunwrap()する習慣は、想定外の入力に対してすぐパニックにつながります。

直し方: yellowblue にします。

この問題を解いてみる →

パターン5

 1  fn main() {
 2      let books = vec!["rust", "python"];
 3      let found = books.iter().find(|&&b| b == "java  ");
                                                     ^
 4      println!("{}", found.unwrap());
 5  }
thread 'main' panicked at main.rs:4:26: called `Option::unwrap()` on a `None` value

見つからない可能性がある処理には、unwrap()の代わりにunwrap_orやmatchを使う方が安全です。

直し方: javarust にします。

この問題を解いてみる →

よくある誤解

「unwrap()は値を取り出すだけの安全な操作のはず」という思い込みは誤りです。unwrap()は中身がNoneだった場合に何もチェックせずパニックする、危険な操作です。

まとめ

called `Option::unwrap()` on a `None` value パニックの原因と直し方は初級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

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