Optionのアンラップ
CoddyのRustジャーニー「Logic & Flow」セクションの一部 — レッスン 38/66。
時には、OptionにSomeが含まれていると確信している場合に、そこから実際の値を取り出す必要があることがあります。Rustはこの目的のために.unwrap()メソッドを提供しています。これはSomeから値を取り出し、直接あなたに渡します。
let maybe_number = Some(42);
let actual_number = maybe_number.unwrap();
println!("The number is: {}", actual_number);Some(value) に対して .unwrap() を呼び出すと、内部の値を返します。上記の例では、actual_number は 42 になり、もはや Option に包まれてはいません。
ただし、重要な注意点があります: None に対して .unwrap() を呼び出すと、プログラムはパニックを起こし、即座にクラッシュします。これにより、.unwrap() は潜在的に危険なメソッドとなり、Option が確実に Some を含んでいると確信できる場合にのみ使用すべきです。
let empty_option: Option<i32> = None;
let value = empty_option.unwrap(); // ここでパニックが発生します!.unwrap() の使用は控えめにし、簡単な例や、すでに .is_some() で確認済みの場合など、Option が値を含んでいることを保証できる状況でのみ使用してください。
チャレンジ
簡単2つの入力を受け取ります。最初の入力は数値(文字列として)、2番目の入力はその数値が有効か無効かを示すインジケータです。2番目の入力が valid の場合は、パースされた数値を含む Some を持つ Option<i32> を作成してください。2番目の入力が invalid の場合は、None を持つ Option<i32> を作成してください。.unwrap() を使用して Option から値を取り出し、それを出力してください。
要件:
- 最初の入力を読み込み、空白をトリミングする
- 2番目の入力を読み込み、空白をトリミングする
.parse::<i32>()を使用して最初の入力をi32にパースするOption<i32>変数を作成する:- 2番目の入力が
validの場合、Some(parsed_number)を割り当てる - 2番目の入力が
invalidの場合、Noneを割り当てる
- 2番目の入力が
.unwrap()を使用してOptionから値を取り出す- 取り出した値を
Value: [number]の形式で出力する
入力:
- 1行目: 文字列としての数値 (例:
42) - 2行目:
validまたはinvalid
出力:
- 2番目の入力が
validの場合:Value: [number] - 2番目の入力が
invalidの場合: プログラムはパニックします(これはこのチャレンジで期待される動作です)
注意: 2番目の入力が invalid の場合、None に対して .unwrap() を呼び出すとパニックが発生します。これは、Option に値が含まれていることが確実でない場合に .unwrap() を使用することの危険性を示しています。
チートシート
.unwrap()メソッドは、Option<T>から値を取り出します:
let maybe_number = Some(42);
let actual_number = maybe_number.unwrap();
println!("The number is: {}", actual_number); // 出力: The number is: 42警告: Noneに対して.unwrap()を呼び出すと、プログラムはパニックを起こしてクラッシュします:
let empty_option: Option<i32> = None;
let value = empty_option.unwrap(); // これはパニックします!Optionが確実にSome値を保持していると確信できる場合にのみ、.unwrap()を使用してください。
自分で試してみよう
use std::io;
fn main() {
// 最初の入力を読み込む(文字列としての数値)
let mut number_input = String::new();
io::stdin().read_line(&mut number_input).expect("Failed to read line");
let number_input = number_input.trim();
// 2番目の入力を読み込む(valid または invalid)
let mut validity_input = String::new();
io::stdin().read_line(&mut validity_input).expect("Failed to read line");
let validity_input = validity_input.trim();
// 数値をパースする
let parsed_number: i32 = number_input.parse().expect("Failed to parse number");
// TODO: 以下にコードを記述してください
// validity_input に基づいて Option<i32> を作成します
// validity_input が "valid" の場合は Some(parsed_number) を割り当てます
// validity_input が "invalid" の場合は None を割り当てます
// 次に .unwrap() を使用して値を取り出し、次の形式で出力します: Value: [number]
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
Logic & Flowのすべてのレッスン
6Optionによる値の欠如の扱い
Optionとは?Optionでmatchを使うis_some() と is_none()Optionのアンラップexpect メソッドデフォルト値の提供:unwrap_orまとめ:要素の検索