Optionでmatchを使う
CoddyのRustジャーニー「Logic & Flow」セクションの一部 — レッスン 36/66。
Optionが何であるかを理解したところで、それを処理するための最も一般的で明示的な方法、つまりmatch式を使用する方法を学びましょう。このアプローチでは、値がある場合とない場合という、考えられる両方のケースを考慮することが強制されます。
match式は、両方のバリアントに対してアームを作成できるため、Optionと完璧に連携します。
let maybe_name = Some("Alice".to_string());
match maybe_name {
Some(name) => println!("Hello, {}!", name),
None => println!("Hello, stranger!"),
}Some(name)アームがSomeバリアントの中から値を取り出していることに注目してください。変数nameは、Optionではなく、実際のStringを保持するようになります。これはデストラクタリング(構造分解)と呼ばれます。つまり、ラッパーから内部の値を取り出しているのです。
Noneアームは値がない場合を処理し、デフォルトメッセージを表示したり、まったく別の操作を行ったりといった代替の動作を提供できるようにします。
チャレンジ
簡単入力として学生の名前を受け取ります。名前はシステムに存在する場合もあれば、欠落している場合もあります。名前が空でない場合は Some(name) を含み、名前が空の場合は None を含む Option<String> を作成してください。match 式を使用して両方のケースを処理し、適切なメッセージを出力してください。
要件:
- 入力を文字列(学生の名前)として読み込む
.trim()を使用して入力から空白を削除するOption<String>変数を作成する:- トリミングされた名前が空でない場合、
Some(name.to_string())を割り当てる - トリミングされた名前が空の場合、
Noneを割り当てる
- トリミングされた名前が空でない場合、
match式を使用してOptionの両方のバリアントを処理するSome(name)アームでは、次のように出力する:Welcome, [name]!Noneアームでは、次のように出力する:No name provided
入力:
- 学生の名前、または空行を含む1行
出力:
- 名前が提供された場合:
Welcome, [name]! - 名前が提供されなかった場合(空の入力):
No name provided
チートシート
match 式を使用して、両方のバリアントのアームを作成することで Option 型の値を処理します。
let maybe_name = Some("Alice".to_string());
match maybe_name {
Some(name) => println!("Hello, {}!", name),
None => println!("Hello, stranger!"),
}Some(name) アームは、デストラクタリング(構造分解)を使用して Some バリアントから内部の値を取り出します。変数 name には、Option ラッパーではなく、実際の値が含まれます。
None アームは値がない場合を処理し、代替の動作を提供できるようにします。
自分で試してみよう
use std::io;
fn main() {
// 入力を読み込む
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Failed to read line");
let name = input.trim();
// TODO: 名前が空かどうかに基づいて Option<String> を作成する
// TODO: match 式を使用して Some と None のケースを処理し、適切なメッセージを表示する
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
Logic & Flowのすべてのレッスン
6Optionによる値の欠如の扱い
Optionとは?Optionでmatchを使うis_some() と is_none()Optionのアンラップexpect メソッドデフォルト値の提供:unwrap_orまとめ:要素の検索