このページの目次
Result と Option
Option は「値が存在しない可能性がある」ことを表し、Result は「操作が失敗する可能性がある」ことを表します。これらは例外ではなく列挙型です。
?演算子は None/Err に遭遇すると早期リターンし、combinator チェーン (map/and_then/or_else) により、エラー処理は try-catch による制御フローのジャンプではなく、型安全なパイプラインとなります。
Option: 値が存在しない可能性がある
find_user
.map // Option<User> → Option<String>、変換
.and_then // Option<String> → Option<Record>、チェーン
.filter // active のみ保持
.unwrap_or; // 抽出またはデフォルト値を使用
各 combinator は Some の場合のみ処理し、None は自動的にショートサーキットします。このパターンは関数型プログラミングにおいて「レールウェイ指向プログラミング」と呼ばれます。成功の軌道に沿って値を渡すか、失敗の軌道に一瞬でジャンプしてそのままそこに留まり、null チェックは行われません。unwrap_or の時点でコンパイラがデフォルト値の提供を強制するため、値の欠落に対する処理を見逃すことはありません。
Result: エラーは値であり、例外ではない
let n = match parse ;
例外との核心的な違い:エラーは戻り値の一部であり、呼び出し元は関数のシグネチャからそれが失敗する可能性があることを知ることができます。隠れた制御フローはなく、「この関数はどのような例外を投げるか」といったことを覚える必要もありません。コンパイラは Result の処理を強制し、#[must_use] 属性により未使用の Result に対してコンパイル警告が発生します。
? 演算子: エラーの早期リターン
展開した同等のコードは以下の通りです:
let file = match read_to_string ;
? は From::from を呼び出して自動的なエラー型の変換を行います。From<io::Error> for MyError が実装されていれば、std::fs::read_to_string()? の io::Error は自動的に MyError に変換されます。これが Rust におけるエラー伝播の鍵であり、各レイヤーで手動でエラーをラップする必要がありません。
main で Result を返す
main が Result を返す場合、main が Err を返すと、ランタイムがエラーを出力して終了します(終了コード 1)。これは単純な CLI ツールに適しています。複雑なアプリケーションでは、通常、独自のエラー処理とログ記録が行われます。
参考
- Rust Book: 第 9 章
- Rust By Example: Option/Result, ?
Keywords: Option, Result, combinator, and_then, ?, error propagation, From trait, #[must_use]