Я читаю документацию поFile
:
//..
let mut file = File::create("foo.txt")?;
//..
Что ?
в этой строке? Я не помню, чтобы видел его раньше в Rust Book.
Я читаю документацию поFile
:
//..
let mut file = File::create("foo.txt")?;
//..
Что ?
в этой строке? Я не помню, чтобы видел его раньше в Rust Book.
Ответы:
Как вы могли заметить, в 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
if 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
.Он предназначен для распространения ошибки для типа исправимой ошибки Result <T, E>. Это раскрывает результат и дает вам внутреннюю ценность.
Вместо того, чтобы обрабатывать случай ошибки, вы распространяете его на вызывающий код и обрабатываете только случай Ok. Преимущество в том, что он устраняет множество шаблонов и упрощает реализацию функций.
источник
.unwrap()
который паникует в случае ошибки.