Для перехвата и обработки ошибки в прошлой теме применялась конструкция match:
fn main() {
let tom_result = create_person("Tom", 36);
let tom = match tom_result{
Ok(person) => person,
Err(err_message) => panic!("Возникла проблема: {}", err_message)
};
println!("Name: {} Age: {}", tom.name, tom.age);
}
struct Person{ name: String, age:u8}
fn create_person(username: &str, userage: u8) -> Result<Person, String>{
if userage < 110{
let new_person = Person{name: String::from(username), age: userage };
Result::Ok(new_person)
}
else {
Result::Err(String::from("Некорректный возраст. Возраст должен быть меньше 110"))
}
}
Причем само получение результата функции как бы разделяется на две части. Сначала получаем собственно результат функции - объект Result:
let tom_result = create_person("Tom", 36);
Затем применяем конструкцию match для получения объекта Person:
let tom = match tom_result{ ..... };
Такой способ может показаться слишком избыточым в плане кода. Нам надо определить слишком много действий, чтобы получить требуемый объект Person. Однако тип Result позволяет упростить работу, предоставляя специальные методы.
Одним из таких методов является unwrap(). Если возвращенный объект Result представляет константу Ok,
то метод unwrap() возвращает объект, который содержится в константе Ok. Но если объект Result представляет
константу Err, то метод unwrap() вызывает макрос panic!.
Так, перепишем предыдущий пример с применением метода unwrap():
fn main() {
let tom = create_person("Tom", 136).unwrap();
println!("Name: {} Age: {}", tom.name, tom.age);
}
struct Person{ name: String, age:u8}
fn create_person(username: &str, userage: u8) -> Result<Person, String>{
if userage < 110{
let new_person = Person{name: String::from(username), age: userage };
Result::Ok(new_person)
}
else {
Result::Err(String::from("Некорректный возраст. Возраст должен быть меньше 110"))
}
}
Если объект Person будет успешно создан, то через переменную tom мы сможем использовать далее в программе.
В случае ошибки мы получим следующее сообщение:
thread 'main' panicked at main.rs:3:41: called `Result::unwrap()` on an `Err` value: "Некорректный возраст. Возраст должен быть меньше 110" note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Метод expect() работает аналогично за тем исключением, что позволяет установить сообщение, которое будет передаваться в макрос panic:
fn main() {
let tom = create_person("Tom", 136).expect("Что-то пошло не так....");
println!("Name: {} Age: {}", tom.name, tom.age);
}
struct Person{ name: String, age:u8}
fn create_person(username: &str, userage: u8) -> Result<Person, String>{
if userage < 110{
let new_person = Person{name: String::from(username), age: userage };
Result::Ok(new_person)
}
else {
Result::Err(String::from("Некорректный возраст. Возраст должен быть меньше 110"))
}
}
Консольный вывод:
thread 'main' panicked at main.rs:3:41: Что-то пошло не так....: "Некорректный возраст. Возраст должен быть меньше 110" note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Еще одну возможность предоставляет метод unwrap_or_else(). Если возвращенный объект Result представляет константу
Ok, то метод unwrap_or_else() возвращает объект, который содержится в константе Ok.
Но если объект Result представляет константу Err, то метод вызывает вызывает передаваемую в качестве параметра функцию.
Эта функция в качестве параметра получает объект ошибки из константы Err и сама определяет логику обработки ошибки. Например:
fn main() {
let tom = create_person("Tom", 136).unwrap_or_else(|error| {
panic!("Возникла проблема: {}", error)
});
println!("Name: {} Age: {}", tom.name, tom.age);
}
struct Person{ name: String, age:u8}
fn create_person(username: &str, userage: u8) -> Result<Person, String>{
if userage < 110{
let new_person = Person{name: String::from(username), age: userage };
Result::Ok(new_person)
}
else {
Result::Err(String::from("Некорректный возраст. Возраст должен быть меньше 110"))
}
}
Здесь в метод unwrap_or_else() передается функция |error| { panic!("Возникла проблема: {}", error); }.
Параметр error - это, что передается в константу Err - в данном случае объект String с сообщением об ошибке.
Консольный вывод:
thread 'main' panicked at main.rs:5:9: Возникла проблема: Некорректный возраст. Возраст должен быть меньше 110 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace