Yomiage
メニュー

Rust実践講座 07:Option・Result・疑問符で失敗を伝える

更新 2026/9/27 6:22:11 公開

投稿者: しゅりりん

到達点は、不在、回復可能な失敗、プログラムの前提違反を区別することです。前提は第06回です。

失敗も戻り値の型へ含める

OptionはSomeかNone、ResultはOkかErrです。検索で見つからないのは通常の不在、数値の読み取り失敗は理由のある失敗として表せます。unwrapは不在や失敗をpanicに変えるため、利用者の入力へ安易に使いません。

fn parse_minutes(input: &str) -> Result<u32, String> {
    let value: u32 = input.trim().parse()
        .map_err(|_| "0以上の整数を指定してください".to_owned())?;
    if value > 1440 {
        return Err("一日分は1440分以下です".to_owned());
    }
    Ok(value)
}

fn total(inputs: &[&str]) -> Result<u32, String> {
    let mut result = 0_u32;
    for input in inputs {
        result = result.checked_add(parse_minutes(input)?)
            .ok_or_else(|| "合計が範囲を超えました".to_owned())?;
    }
    Ok(result)
}

fn main() {
    println!("{:?}", total(&["25", "15"]));
    println!("{:?}", total(&["25", "abc"]));
    let titles = ["基礎", "演習"];
    println!("{}", titles.get(5).unwrap_or(&"見つかりません"));
}

src/main.rsの出力はOkの40、Errの説明、不在のメッセージです。疑問符は成功なら中身を取り出し、失敗なら現在の関数から早く返します。例外のように任意の場所へ飛ぶ構文としてではなく、戻り値の型と対応させて読みます。

エラー型も契約

小さなアプリではStringのエラーで始められます。呼び出し側が種類ごとに判断するライブラリなら、Parse、OutOfRange、Ioなどのenumで表す方が適切です。DisplayとErrorを実装すれば、説明と原因の連鎖も表現できます。

mapは成功値の変換、map_errは失敗値の変換、and_thenは次もResultを返す処理の接続に使います。覚える前にmatchで同じ処理を書いてみると意味を理解できます。panicは、予期する入力エラーの通常の伝達手段にはしません。

練習と解答

練習:不正な一行を飛ばして合計する仕様に変えるとき、疑問符をそのまま使えるでしょうか。

解答:その場所の疑問符は最初の失敗で関数を終了させます。行ごとにmatchして、成功値を足し、失敗した行番号と理由を別に集める設計へ変えます。読み飛ばしを利用者へ伝え、完全な集計と混同させないことが大切です。

公式資料

Resultによるエラー処理を参照できます。


Rust全20回の目次 | 前の回 | 次の回

このブラウザでは Web Speech API が利用できません。

1 / 15 · 停止中