О чем говорит этот вопрос?

Я читаю документацию для File:

//..
let mut file = File::create("foo.txt")?;
//..

Что такое ? в этой строке? Я не помню, чтобы это видели в Ранней Книге.

Ответ 1

Как вы могли заметить, у Руста нет исключений. У этого есть паника, но их функциональность ограничена (они не могут нести структурированную информацию), и их использование для обработки ошибок не рекомендуется (они предназначены для неустранимых ошибок).

В 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,
        e => return e,
    };

    // use `i`
}

Это здорово, потому что:

  • при написании кода вы не можете случайно забыть об ошибке,
  • при чтении кода вы можете сразу увидеть, что существует вероятность ошибки здесь.

Это меньше идеала, однако, в том, что он очень многословный. Здесь находится оператор вопросительного знака ?.

Вышеприведенное может быть переписано как:

fn do_the_thing(i: i32) -> Result<i32, Error> {
    let i = halves_if_even(i)?;

    // use `i`
}

что намного более кратким.

Что ? здесь эквивалентно приведенному выше выражению match. Короче: он распаковывает Result, если "ОК", и возвращает ошибку, если нет.

Это немного магия, но обработка ошибок требует некоторого волшебства, чтобы вырезать шаблон, и в отличие от исключений сразу видно, какие вызовы функций могут или не могут быть обнулены: те, которые украшены ?.