Я читаю документацію дляFile
:
//..
let mut file = File::create("foo.txt")?;
//..
Що ?
в цьому рядку? Я не пам’ятаю, щоб бачив це раніше в Книзі іржі.
Я читаю документацію дляFile
:
//..
let mut file = File::create("foo.txt")?;
//..
Що ?
в цьому рядку? Я не пам’ятаю, щоб бачив це раніше в Книзі іржі.
Відповіді:
Як ви могли помітити, Руст не має винятків. У нього є паніка, але їх функціональність обмежена (вони не можуть нести структуровану інформацію), і їх використання для обробки помилок не рекомендується (вони призначені для невиправлених помилок).
У 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
.
Він призначений для поширення помилок для відновлюваного типу помилки Результат <T, E>. Це розгортає результат і надає вам внутрішню цінність.
Замість того, щоб обробляти випадки помилки, ви розповсюджуєте їх на код абонента і маєте справу лише з випадком Ok. Перевага полягає в тому, що це усуває велику кількість шаблонів та спрощує реалізацію функції.
.unwrap()
який панікує у випадку помилки.