I'm reading the documentation for File
:
//..
let mut file = File::create("foo.txt")?;
//..
What is the ?
in this line? I do not recall seeing it in the Rust Book before.
ベストアンサー1
As you may have noticed, Rust does not have exceptions. It has panics, but their use for error-handling is discouraged (they are meant for unrecoverable errors).
In Rust, error handling uses Result
. A typical example would be:
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`
}
This is great because:
- when writing the code you cannot accidentally forget to deal with the error,
- when reading the code you can immediately see that there is a potential for error right here.
It's less than ideal, however, in that it is very verbose. This is where the question mark operator ?
comes in.
The above can be rewritten as:
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = halves_if_even(i)?;
// use `i`
}
which is much more concise.
What ?
does here is equivalent to the match
statement above with an addition. In short:
- It unpacks the
Result
if OK - It returns the error if not, calling
From::from
on the error value to potentially convert it to another type.
少し魔法のようですが、エラー処理には定型文を削減するための魔法が必要であり、例外とは異なり、どの関数呼び出しがエラーになるか、またはエラーにならないかがすぐにわかります。つまり、 で装飾されている関数呼び出しです?
。
この魔法の一例としては、次の場合にもこれが機能するという点があります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`
}
Rust バージョン 1.13.0 で安定化された演算子?
は、(unstable)特性によって強化されています。Try
参照: