Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
Result<T, E> / Ok / Err
『Result<T, E>』は処理の成功(『Ok』)と失敗(『Err』)を型で表す列挙型です。Rustでは例外の代わりに『Result』を使うことで、エラーの可能性をコンパイル時に強制的に処理させます。
構文
// 成功値をOkで包みます。
let ok: Result<i32, String> = Ok(42);
// エラー値をErrで包みます。
let err: Result<i32, String> = Err(String::from("エラーが発生しました。"));
// matchで成功・失敗を分岐します。
match result {
Ok(value) => println!("成功: {}", value),
Err(e) => println!("失敗: {}", e),
}
// if letで成功時だけ処理します。
if let Ok(value) = result {
println!("成功: {}", value);
}
構文一覧
| 構文・バリアント | 概要 |
|---|---|
| Ok(値) | 処理が成功したことを表すバリアントです。成功時の結果値を保持します。 |
| Err(エラー値) | 処理が失敗したことを表すバリアントです。エラーの詳細情報を保持します。エラー型は任意の型を使えます。 |
| match | 『Ok(v)』と『Err(e)』の2パターンで分岐します。両パターンの処理を強制するためエラーの見落としを防ぎます。 |
| if let Ok(v) | 成功時だけ処理するシンタックスシュガーです。エラーを無視するため乱用は避けてください。 |
| is_ok() / is_err() | 結果が成功か失敗かを真偽値で返します。処理は行わず判定だけしたい場合に使います。 |
サンプルコード
// 割り算を行い、0除算はErrで返す関数です。
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
Err(String::from("0で割ることはできません。"))
} else {
Ok(a / b)
}
}
fn main() {
// 成功ケースをmatchで処理します。
match divide(10.0, 2.0) {
Ok(result) => println!("結果: {}", result),
Err(e) => println!("エラー: {}", e),
}
// 失敗ケースをmatchで処理します。
match divide(10.0, 0.0) {
Ok(result) => println!("結果: {}", result),
Err(e) => println!("エラー: {}", e),
}
// is_ok / is_errで状態を確認します。
let r1 = divide(10.0, 2.0);
let r2 = divide(10.0, 0.0);
println!("r1 is_ok: {}", r1.is_ok()); // true
println!("r2 is_err: {}", r2.is_err()); // true
// 標準ライブラリのパース失敗もResultで返ります。
let parsed: Result<i32, _> = "42".parse();
println!("{:?}", parsed); // Ok(42)
let failed: Result<i32, _> = "abc".parse();
println!("{:?}", failed); // Err(...)
}
概要
『Result<T, E>』の型パラメータ『T』は成功値の型、『E』はエラー値の型です。エラー型には標準ライブラリの『std::io::Error』やカスタム型など、任意の型を使えます。『Result』を返す関数の戻り値を使わずに捨てるとコンパイラが警告を出します。エラーは必ず処理するか、明示的に無視してください。
Rustの標準ライブラリのファイル操作・ネットワーク・パース処理など、失敗しうるほぼすべての操作が『Result』を返します。他の言語の try-catch に相当しますが、Rustでは例外が存在しないため、エラーを戻り値として明示的に扱うことがRustらしい設計です。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。