0Pricing
Learn Rust Coding · Урок

Преобразование ошибок

Реализации 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 — локальная установка не требуется.

Все уроки этого курса

  1. Result и оператор ?
  2. thiserror
  3. anyhow
  4. Преобразование ошибок
← Назад к Learn Rust Coding