Преобразование ошибок
Реализации From
«Преобразование ошибок» — бесплатный урок Learn Rust Coding на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Learn Rust Coding, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Learn Rust Coding содержит 4 уроков всего.
Зачем преобразовывать ошибки?
Разные уровни кода создают разные типы ошибок. Чтобы передавать их через одну функцию, нужно преобразовать ошибки нижнего уровня в единый тип. Rust делает это с помощью трейта From.
Трейт From
From<T> определяет, как создать один тип из другого. Реализовав его для своего типа ошибки, Вы сможете преобразовывать в него исходные ошибки.
trait From<T> {
fn from(value: T) -> Self;
}Как ? использует From
Когда Вы пишете expr?, а тип ошибки отличается от типа ошибки, возвращаемого функцией, оператор вызывает From::from для преобразования. На этом основана удобная автоматическая передача ошибок.
Единый тип ошибки
Определите перечисление, способное хранить каждый вид ошибки, который может выдать Ваша функция.
#[derive(Debug)]
enum AppError {
Io(std::io::Error),
Parse(std::num::ParseIntError),
}Реализация From
Напишите реализацию From для каждой исходной ошибки, чтобы преобразовывать её в соответствующий вариант.
impl From<std::io::Error> for AppError {
fn from(e: std::io::Error) -> Self {
AppError::Io(e)
}
}
impl From<std::num::ParseIntError> for AppError {
fn from(e: std::num::ParseIntError) -> Self {
AppError::Parse(e)
}
}Автоматическая передача
После добавления этих реализаций ? бесплатно преобразует каждую ошибку в AppError.
fn read_count(path: &str) -> Result<i32, AppError> {
let text = std::fs::read_to_string(path)?; // io::Error -> AppError
let n: i32 = text.trim().parse()?; // ParseIntError -> AppError
Ok(n)
}Into — обратная сторона
Реализация From<A> for B автоматически предоставляет A: Into<B>. Предпочитайте реализовывать From: так Вы бесплатно получаете into().
fn make() -> AppError {
let e: std::io::Error = std::io::Error::other("boom");
e.into() // uses From<io::Error> for AppError
}Помещение объектов трейтов в Box
Для быстрых преобразований Box<dyn Error> принимает любой тип ошибки, поскольку стандартная библиотека предоставляет для него универсальные реализации From.
use std::error::Error;
fn run() -> Result<(), Box<dyn Error>> {
let n: i32 = "42".parse()?; // ParseIntError -> Box<dyn Error>
println!("{n}");
Ok(())
}Ящики, создающие From
Писать каждую реализацию From вручную утомительно. Атрибут #[from] ящика thiserror создаёт их, а anyhow автоматически преобразует всё в один тип.
Выбор подхода
Краткий обзор стратегий преобразования:
- Ручные реализации
From— полный контроль, больше кода thiserror #[from]— типизированные ошибки, автоматически созданные реализацииBox<dyn Error>илиanyhow— минимум шаблонного кода
Добавление контекста при преобразовании
Реализация From может не только обернуть ошибку, но и дополнить её. Здесь преобразование добавляет дополнительный контекст, делая итоговую ошибку более информативной.
impl From<std::num::ParseIntError> for AppError {
fn from(e: std::num::ParseIntError) -> Self {
// could log or annotate here before wrapping
AppError::Parse(e)
}
}Быстрая проверка
Какой трейт использует оператор ? для преобразования одного типа ошибки в другой?
Итоги
Вы изучили преобразование ошибок:
?преобразует ошибки через трейтFrom- Реализуйте
From<Source>для своего перечисления ошибок Fromбесплатно предоставляетIntoиinto()Box<dyn Error>принимает любую ошибкуthiserrorиanyhowавтоматизируют шаблонный код
Часто задаваемые вопросы
Урок «Преобразование ошибок» бесплатный?
Да — полный текст урока «Преобразование ошибок» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Learn Rust Coding, подпишись на CoddyKit PRO. Курс Learn Rust Coding содержит 4 уроков всего.
Чему я научусь в уроке «Преобразование ошибок»?
Реализации From Ты практикуешь Learn Rust Coding с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Learn Rust Coding?
Предыдущий опыт не требуется. Learn Rust Coding на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Преобразование ошибок»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Learn Rust Coding?
Да. Каждый урок Learn Rust Coding включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Result и оператор ?
- thiserror
- anyhow
- Преобразование ошибок