РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
615 of 1245 menu

Свои типы ошибок

В Rust можно создавать собственные типы ошибок с помощью перечислений (enum) или структур (struct). Это даёт возможность точно описать, какие ошибки могут возникнуть в программе, и обрабатывать их отдельно. Обычно собственный тип ошибки реализует трейты Debug, Display и Error, что позволяет использовать его совместно с оператором ? и стандартными средствами обработки ошибок.

Синтаксис

#[derive(Debug)] enum MyError { Variant1, Variant2, } impl std::fmt::Display for MyError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { MyError::Variant1 => write!(f, "error variant 1"), MyError::Variant2 => write!(f, "error variant 2"), } } } impl std::error::Error for MyError {}

Пример

Давайте создадим собственный тип ошибки с двумя вариантами и функцией, которая возвращает ошибку при определённом условии:

use std::fmt; #[derive(Debug)] enum MyError { EmptyInput, TooShort, } impl fmt::Display for MyError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { MyError::EmptyInput => write!(f, "input is empty"), MyError::TooShort => write!(f, "input is too short"), } } } impl std::error::Error for MyError {} fn check(s: &str) -> Result<(), MyError> { if s.is_empty() { return Err(MyError::EmptyInput); } if s.len() < 3 { return Err(MyError::TooShort); } Ok(()) } fn main() { let res = check("ab"); println!("{:?}", res); }

Результат выполнения кода:

Err(TooShort)

Пример

Давайте обработаем собственную ошибку с помощью match и выведем понятное сообщение:

use std::fmt; #[derive(Debug)] enum MyError { EmptyInput, TooShort, } impl fmt::Display for MyError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { MyError::EmptyInput => write!(f, "input is empty"), MyError::TooShort => write!(f, "input is too short"), } } } impl std::error::Error for MyError {} fn check(s: &str) -> Result<(), MyError> { if s.is_empty() { return Err(MyError::EmptyInput); } if s.len() < 3 { return Err(MyError::TooShort); } Ok(()) } fn main() { match check("abcde") { Ok(()) => println!("ok"), Err(e) => println!("error: {}", e), } }

Результат выполнения кода:

"ok"

Пример

Давайте используем собственный тип ошибки вместе с оператором ? для проброса ошибки из функции:

use std::fmt; #[derive(Debug)] enum MyError { EmptyInput, TooShort, } impl fmt::Display for MyError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { MyError::EmptyInput => write!(f, "input is empty"), MyError::TooShort => write!(f, "input is too short"), } } } impl std::error::Error for MyError {} fn check(s: &str) -> Result<usize, MyError> { if s.is_empty() { return Err(MyError::EmptyInput); } if s.len() < 3 { return Err(MyError::TooShort); } Ok(s.len()) } fn run(s: &str) -> Result<usize, MyError> { let len = check(s)?; Ok(len * 2) } fn main() { let res = run("abcde"); println!("{:?}", res); }

Результат выполнения кода:

Ok(10)

Смотрите также

  • трейт Error,
    который представляет базовый трейт для всех ошибок
  • оператор ?,
    который пробрасывает ошибку из функции
  • функция panic!,
    которая останавливает программу при критической ошибке
  • метод unwrap,
    который извлекает значение или вызывает панику
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить