Альтернативой упаковке ошибок является оборачивание их в ваш собственный тип.
use std::error;
use std::num::ParseIntError;
use std::fmt;
type Result = std::result::Result;
#[derive(Debug)]
enum DoubleError {
EmptyVec,
// Мы не будем обрабатывать ошибку разбора сами, а передадим её в программу.
// Предоставление дополнительной информации требует добавления дополнительных данных к типу
Parse(ParseIntError),
}
impl fmt::Display for DoubleError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
DoubleError::EmptyVec =>
write!(f, "пожалуйста используйте вектор хотя бы с одним элементом"),
// Это адаптер, так что обратимся к нижележащей реализации `fmt`.
DoubleError::Parse(ref e) => e.fmt(f),
}
}
}
impl error::Error for DoubleError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
DoubleError::EmptyVec => None,
// Причиной ошибки является адаптированный тип. Здесь происходит
// неявное преобразование к типажу `&error::Error`. Это работает
// так как основной тип реализует типаж `Error`.
DoubleError::Parse(ref e) => Some(e),
}
}
}
// Реализуем преобразование из `ParseIntError` в `DoubleError`.
// Это преобразование будет автоматически вызвано оператором `?`,
// если будет необходимо преобразовать `ParseIntError` в `DoubleError`.
impl From for DoubleError {
fn from(err: ParseIntError) -> DoubleError {
DoubleError::Parse(err)
}
}
fn double_first(vec: Vec<&str>) -> Result {
let first = vec.first().ok_or(DoubleError::EmptyVec)?;
let parsed = first.parse::()?;
Ok(2 * parsed)
}
fn print(result: Result) {
match result {
Ok(n) => println!("Первое удвоение {}", n),
Err(e) => println!("Ошибка: {}", e),
}
}
fn main() {
let numbers = vec!["42", "93", "18"];
let empty = vec![];
let strings = vec!["tofu", "93", "18"];
print(double_first(numbers));
print(double_first(empty));
print(double_first(strings));
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Это добавляет чуть больше шаблонного кода для обработки ошибок и может быть не нужно всем приложениям. Есть библиотеки, которые могут избавить вас от написания этого шаблонного кода.
From::from и Enums