私は以下のドキュメントをFile
読んでいます:
//..
let mut file = File::create("foo.txt")?;
//..
?
この行には何がありますか?以前にRustBookで見たのを覚えていません。
私は以下のドキュメントをFile
読んでいます:
//..
let mut file = File::create("foo.txt")?;
//..
?
この行には何がありますか?以前にRustBookで見たのを覚えていません。
回答:
お気づきかもしれませんが、Rustには例外はありません。パニックが発生しますが、機能が制限され(構造化された情報を伝達できません)、エラー処理に使用することはお勧めしません(回復不能なエラーを対象としています)。
Rustでは、エラー処理はを使用しResult
ます。典型的な例は次のとおりです。
fn halves_if_even(i: i32) -> Result<i32, Error> {
if i % 2 == 0 {
Ok(i / 2)
} else {
Err(/* something */)
}
}
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = match halves_if_even(i) {
Ok(i) => i,
Err(e) => return Err(e),
};
// use `i`
}
これは素晴らしい理由です:
ただし、非常に冗長であるという点で理想的とは言えません。これが疑問符演算子の?
出番です。
上記は次のように書き直すことができます。
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = halves_if_even(i)?;
// use `i`
}
これははるかに簡潔です。
何?
ここで行うことは同等ですmatch
上記のステートメント。つまりResult
、OKの場合は解凍し、そうでない場合はエラーを返します。
少し魔法ですが、エラー処理には定型文を削減するための魔法が必要です。例外とは異なり、どの関数呼び出しがエラーになるかどうかがすぐにわかり?
ます。
魔法の一例は、これが次の場合にも機能することですOption
。
// Assume
// fn halves_if_even(i: i32) -> Option<i32>
fn do_the_thing(i: i32) -> Option<i32> {
let i = halves_if_even(i)?;
// use `i`
}
これは、(不安定な)Try
特性によって強化されています。
参照:
Result
またはOption
。