0Pricing
Learn Rust Coding · Lekcja

Konwersja błędów

Implementacje From

Konwersja błędów to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Learn Rust Coding, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Po co konwertować błędy?

Różne warstwy kodu generują różne typy błędów. Aby przekazywać je przez jedną funkcję, trzeba konwertować błędy niższego poziomu na ujednolicony typ. Rust realizuje to za pomocą traitu From.

Trait From

From<T> definiuje sposób tworzenia jednego typu na podstawie innego. Zaimplementowanie go dla własnego typu błędu pozwala konwertować na niego błędy źródłowe.

trait From<T> {
    fn from(value: T) -> Self;
}

Jak ? używa From

Gdy zapisze Pan/Pani expr?, a typ błędu różni się od typu błędu zwracanego przez funkcję, operator wywołuje From::from, aby go przekonwertować. Na tym mechanizmie opiera się płynne przekazywanie błędów.

Ujednolicony typ błędu

Należy zdefiniować enum przechowujący każdy rodzaj błędu, który może wygenerować funkcja.

#[derive(Debug)]
enum AppError {
    Io(std::io::Error),
    Parse(std::num::ParseIntError),
}

Implementowanie From

Należy napisać implementację From dla każdego błędu źródłowego, aby był konwertowany na odpowiadający mu wariant.

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)
    }
}

Automatyczne przekazywanie błędów

Po dodaniu tych implementacji ? bez dodatkowego kodu konwertuje każdy błąd na 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 jest drugą stroną From

Zaimplementowanie From<A> for B automatycznie zapewnia A: Into<B>. Warto implementować From, ponieważ into() otrzymuje się bez dodatkowej pracy.

fn make() -> AppError {
    let e: std::io::Error = std::io::Error::other("boom");
    e.into() // uses From<io::Error> for AppError
}

Opakowywanie obiektów traitów

Do szybkich konwersji można użyć Box<dyn Error>, który akceptuje dowolny typ błędu, ponieważ biblioteka standardowa udostępnia ogólne implementacje From konwertujące do tego typu.

use std::error::Error;

fn run() -> Result<(), Box<dyn Error>> {
    let n: i32 = "42".parse()?; // ParseIntError -> Box<dyn Error>
    println!("{n}");
    Ok(())
}

Crate generujące From

Ręczne pisanie każdej implementacji From jest żmudne. Atrybut #[from] w crate thiserror generuje je automatycznie, a anyhow automatycznie konwertuje wszystko na jeden typ.

Wybór podejścia

Podsumowanie strategii konwersji:

  • Ręczne implementacje From — pełna kontrola, więcej kodu
  • thiserror #[from] — typowane błędy, generowane implementacje
  • Box<dyn Error> lub anyhow — minimum dodatkowego kodu

Dodawanie kontekstu podczas konwersji

Implementacja From może robić więcej niż tylko opakowywać błąd — może go wzbogacać. W tym przypadku konwersja dołącza dodatkowy kontekst, dzięki czemu końcowy błąd jest bardziej szczegółowy.

impl From<std::num::ParseIntError> for AppError {
    fn from(e: std::num::ParseIntError) -> Self {
        // could log or annotate here before wrapping
        AppError::Parse(e)
    }
}

Szybkie sprawdzenie

Jakiego traitu operator ? używa do konwersji jednego typu błędu na inny?

Podsumowanie

Poznał(a) Pan/Pani konwersję błędów:

  • ? konwertuje błędy za pomocą traitu From
  • Należy zaimplementować From<Source> dla własnego enuma błędów
  • From zapewnia bez dodatkowej pracy Into i into()
  • Box<dyn Error> akceptuje dowolny błąd
  • thiserror i anyhow automatyzują powtarzalny kod

Często zadawane pytania

Czy lekcja „Konwersja błędów” jest bezpłatna?

Tak — pełny tekst „Konwersja błędów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Learn Rust Coding, przejdź na CoddyKit PRO. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Co nauczysz się w „Konwersja błędów”?

Implementacje From Ćwiczysz Learn Rust Coding z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Learn Rust Coding?

Nie wymagamy żadnego doświadczenia. Learn Rust Coding w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Konwersja błędów”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Learn Rust Coding?

Tak. Każda lekcja Learn Rust Coding zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Result i operator ?
  2. thiserror
  3. anyhow
  4. Konwersja błędów
← Powrót do Learn Rust Coding