ショートカット: unwrap と expect
CoddyのRustジャーニー「Logic & Flow」セクションの一部 — レッスン 45/66。
すでに Option で .unwrap() と .expect() について学びましたが、これらの同じメソッドは Result でも同様に動作します。しかし、成功と失敗のケースを扱う際、その動作はわずかに異なります。
.unwrap()メソッドはOkバリアントから値を取り出しますが、ResultがErrの場合、プログラムはパニックを起こしてクラッシュします。同様に、.expect()も同じことを行いますが、デバッグを容易にするためのカスタムパニックメッセージを指定することができます:
let success: Result = Ok(42);
let value = success.expect("This should work!");
println!("Value: {}", value); // 出力: Value: 42
// これはカスタムメッセージとともにパニックを起こします:
// let failure: Result = Err("Something went wrong");
// let value = failure.expect("This should work!"); // パニックが発生します!これらのメソッドは成功した値への迅速なアクセスを提供しますが、注意して使用する必要があります。これらは、操作が成功することが完全に確実な場合、または開発やテストの際に最も適しています。
チャレンジ
簡単2つの入力を受け取ります。最初の入力は数値(文字列として)、2番目の入力はステータスインジケータ(ok または error)です。ステータスに基づいて Result<i32, &'static str> を作成してください。ステータスが ok の場合は、パースされた数値を含む Ok を作成します。ステータスが error の場合は、メッセージ "Invalid operation" を持つ Err を作成します。カスタムメッセージを指定した .expect() を使用して Result から値を取り出し、それを表示してください。
要件:
- 最初の入力(数値)を読み込み、空白をトリミングする
- 最初の入力を
i32にパースする - 2番目の入力(ステータス)を読み込み、空白をトリミングする
Result<i32, &'static str>変数を作成する:- ステータスが
okの場合、Ok(parsed_number)を割り当てる - ステータスが
errorの場合、Err("Invalid operation")を割り当てる
- ステータスが
.expect("Failed to get value")を使用してResultから値を取り出す- 取り出した値を
Value: [value]の形式で出力する
入力:
- 1行目: 数値 (例:
75) - 2行目:
okまたはerror
出力:
- ステータスが
okの場合:Value: [number] - ステータスが
errorの場合: プログラムはカスタムメッセージとともにパニックします(このチャレンジではテストされません)
注意: このチャレンジでは、正常な実行を保証するために、テストケースは ok ステータスのみを使用します。error ケースはパニックを引き起こしますが、これは Err に遭遇した際の .expect() の期待される動作です。
チートシート
.unwrap() と .expect() メソッドは、Result 型と連携して Ok バリアントから値を取り出します。
.unwrap() は Ok から値を取り出しますが、Result が Err の場合はパニック(panic)を起こします:
let success: Result<i32, &str> = Ok(42);
let value = success.unwrap();
println!("Value: {}", value); // 出力: Value: 42.expect() も同様に動作しますが、デバッグを容易にするためにカスタムのパニックメッセージを指定できます:
let success: Result<i32, &str> = Ok(42);
let value = success.expect("This should work!");
println!("Value: {}", value); // 出力: Value: 42
// これはカスタムメッセージとともにパニックを起こします:
let failure: Result<i32, &str> = Err("Something went wrong");
let value = failure.expect("This should work!"); // カスタムメッセージとともにパニックを起こしますこれらのメソッドは、Result が Err の場合にプログラムをクラッシュさせるため、注意して使用する必要があります。これらは、操作が成功することが確実な場合や、開発およびテスト中に最も適しています。
自分で試してみよう
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();
// 数値をi32型にパースする
let parsed_number: i32 = number_input.parse().expect("Failed to parse number");
// 2番目の入力(ステータス)を読み込む
let mut status = String::new();
io::stdin().read_line(&mut status).expect("Failed to read line");
let status = status.trim();
// TODO: 以下にコードを記述してください
// ステータスに基づいてResult<i32, &'static str>を作成する
// .expect()を使用して値を取り出す
// 結果を「Value: [value]」の形式で出力する
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
Logic & Flowのすべてのレッスン
7'Result' によるエラーハンドリング
'Result' とは?'Result' で 'match' を使うis_ok() と is_err()ショートカット: unwrap と expectクエスチョンマーク演算子 '?'文字列から数値へのパースまとめ - 安全な除算関数