Введение
В этом практическом занятии мы узнаем о операторе ? в Rust, который позволяет упростить обработку ошибок, возвращая Err вместо аварийного завершения программы, и мы также изучим макрос try!, который обеспечивал аналогичную функциональность до появления оператора ?.
Примечание: Если в практическом занятии не указано имя файла, вы можете использовать любое имя файла, которое хотите. Например, вы можете использовать
main.rs, скомпилировать и запустить его с помощьюrustc main.rs &&./main.
Введение в оператор ?
Иногда нам просто нужна простота метода unwrap, но без возможности аварийного завершения программы (panic). До сих пор unwrap заставлял нас вкладываться все глубже и глубже, когда на самом деле мы хотели получить переменную и выйти из функции. Именно для этого и существует оператор ?.
При обнаружении Err есть два допустимых действия:
panic!, которое мы уже решили尽量避免,если это возможноreturn, потому чтоErrозначает, что ошибка не может быть обработана
Оператор ? почти[^†] эквивалентен методу unwrap, который returnит вместо того, чтобы вызывать panic при возникновении Err. Посмотрим, как мы можем упростить предыдущий пример, использующий комбинаторы:
use std::num::ParseIntError;
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
let first_number = first_number_str.parse::<i32>()?;
let second_number = second_number_str.parse::<i32>()?;
Ok(first_number * second_number)
}
fn print(result: Result<i32, ParseIntError>) {
match result {
Ok(n) => println!("n is {}", n),
Err(e) => println!("Error: {}", e),
}
}
fn main() {
print(multiply("10", "2"));
print(multiply("t", "2"));
}
Макрос try!
До появления оператора ? ту же функциональность можно было реализовать с помощью макроса try!. Теперь рекомендуется использовать оператор ?, но вы по-прежнему можете встретить try! в старом коде. То же самое функция multiply из предыдущего примера, написанная с использованием try!, будет выглядеть так:
// Чтобы скомпилировать и запустить этот пример без ошибок при использовании Cargo, измените значение
// поля `edition` в разделе `[package]` файла `Cargo.toml` на "2015".
use std::num::ParseIntError;
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
let first_number = try!(first_number_str.parse::<i32>());
let second_number = try!(second_number_str.parse::<i32>());
Ok(first_number * second_number)
}
fn print(result: Result<i32, ParseIntError>) {
match result {
Ok(n) => println!("n is {}", n),
Err(e) => println!("Error: {}", e),
}
}
fn main() {
print(multiply("10", "2"));
print(multiply("t", "2"));
}
Резюме
Поздравляем! Вы завершили практическое занятие по введению в оператор ?. Вы можете выполнить больше практических заданий в LabEx, чтобы улучшить свои навыки.