What is this question mark operator about?

2019-01-17 20:03发布

问题:

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 functionality is limited (they cannot carry structured information) and 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,
        e => return 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. In short: it unpacks the Result if OK and returns the error if not.

It's a bit magic, but error handling needs some magic to cut down the boilerplate, and unlike exceptions it is immediately visible which function calls may or may not error out: those that are adorned with ?.

See also:

  • Is the question mark operator ? equivalent to the try! macro?


标签: rust