Przejdź do głównej treści
eLearner.app
Moduł 2 · Lekcja 5 z 510/50 w kursie~12 min
Lekcje modułu (5/5)

Błędy: wzorzec `if err != nil`

W Go błędy to wartości, a nie wyjątki. Funkcja, która może niepowodzenie zwraca błąd jako ostatnią wartość, a osoba wywołująca go sprawdza wyraźnie. Jest jednoznaczny, przewidywalny, łatwy do przetestowania – cena taka trochę więcej gadatliwości.

Interfejs error

error to mały interfejs wbudowany w język:

Go
type error interface {
    Error() string
}

Każdy typ, który implementuje Error() string, to error.

Podstawowy wzór

Go
v, err := operazione()
if err != nil {
    // gestisci o propaga
    return err
}
// usa v

Zobaczysz to tysiące razy: jest to idiomatyczny kod dla każdego omylne wezwanie. Nie czuj się winny z powodu powtórzeń – to cecha, a nie błąd.

Błędy budowania: errors.New i fmt.Errorf

Go
import (
    "errors"
    "fmt"
)

err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)

fmt.Errorf jest idealny, jeśli chcesz dołączyć zmienne do wiadomości.

Zawijanie za pomocą %w

Aby propagować błąd dodając kontekst BEZ utraty oryginału:

Go
f, err := os.Open(path)
if err != nil {
    return fmt.Errorf("config: %w", err)
}

%w „zawija” oryginalny błąd, który można później odzyskać za pomocą errors.Is (równość dla strażników) lub errors.As (dla typu betonu):

Go
if errors.Is(err, os.ErrNotExist) {
    // file inesistente, gestione speciale
}

Błędy Sentinela

Są to błędy eksportowane jako zmienne, używane do porównań z errors.Is:

Go
var ErrNotFound = errors.New("non trovato")

func find(id int) (Item, error) {
    // ...
    return Item{}, ErrNotFound
}

// chiamante:
if errors.Is(err, ErrNotFound) { ... }

panic i recover (podgląd)

panic istnieje w Go, ale jest zarezerwowany dla nieodwracalnych błędów (np. błędów, naruszone niezmienniki), a nie dla normalnego przepływu sterowania. Wejdziemy głębiej moduł Functions z defer/recover. Na razie: nie używaj na miejscu wzorca if err != nil.

Spróbuj

Ćwiczenie#go.m2.l5.e1
Próby: 0Ładowanie...

Obsłuż błąd strconv.Atoi: jeśli err != nil, wypisz go i wróć; w przeciwnym razie wydrukuj nr.

Ładowanie edytora...
Pokaż wskazówkę

Wzór kanoniczny: sprawdź `err != nil`, zaloguj/zwróć, a następnie użyj `n`.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie#go.m2.l5.e2
Próby: 0Ładowanie...

Zaimplementuj SafeDiv: jeśli b == 0 zwróć 0 i błędy.New('dzielenie przez zero'); w przeciwnym razie a/b i zero.

Ładowanie edytora...
Pokaż wskazówkę

Sprawdź `b == 0` PRZED podziałem, aby uniknąć paniki w czasie wykonywania.

Rozwiązanie dostępne po 3 próbach

Quiz#go.m2.l5.e3
Gotowe

Jaki jest idiomatyczny wzorzec obsługi błędu w Go?

Go
v, err := f()
// poi?
Opcje odpowiedzi

Podsumowanie

  • error to interfejs z jedną metodą Error() string.
  • Wzór kanoniczny: v, err := f(); if err != nil { return err }.
  • Kompiluj błędy za pomocą errors.New(msg) lub fmt.Errorf("ctx: %w", err).
  • Użyj %w do owijania i errors.Is / errors.As do sprawdzenia łańcucha.
  • panic tylko dla nieodwracalnych błędów, NIE dla normalnego przepływu sterowania.