Модульні уроки (5/5)
Помилки: шаблон `if err != nil`
У Go помилки є значеннями, а не винятками. Функція, яка може fail повертає помилку як останнє значення, і абонент перевіряє її явно. Це чітко, передбачувано, легко перевірити — ціна є трохи більше багатослівності.
Інтерфейс error
error — це невеликий інтерфейс, вбудований у мову:
type error interface {
Error() string
}Будь-який тип, який реалізує Error() string, є error.
Фундаментальна закономірність
v, err := operazione()
if err != nil {
// gestisci o propaga
return err
}
// usa vВи побачите це тисячі разів: це ідіоматичний код для кожного помилковий виклик. Не відчувайте провини за повторення — це особливість, а не помилка.
Помилки збірки: errors.New та fmt.Errorf
import (
"errors"
"fmt"
)
err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)fmt.Errorf ідеально підходить, якщо ви хочете включити змінні в повідомлення.
Обгортка з %w
Щоб поширити помилку додавання контексту БЕЗ втрати оригіналу:
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("config: %w", err)
}%w "загортає" вихідну помилку, яку можна виправити пізніше за допомогою
errors.Is (рівність для дозорних) або errors.As (для конкретного типу):
if errors.Is(err, os.ErrNotExist) {
// file inesistente, gestione speciale
}Дозорні помилки
Це помилки, експортовані як змінні, які використовуються для порівняння з errors.Is:
var ErrNotFound = errors.New("non trovato")
func find(id int) (Item, error) {
// ...
return Item{}, ErrNotFound
}
// chiamante:
if errors.Is(err, ErrNotFound) { ... }panic та recover (попередній перегляд)
panic існує в Go, але зарезервовано для невиправних помилок (наприклад, помилки,
порушені інваріанти), не для нормального потоку керування. Ми підемо глибше
модуль Функції з defer/recover. Наразі: не використовуйте його на місці
шаблону if err != nil.
Спробуйте
Обробка помилки з strconv.Atoi: якщо err != nil, вивести її та повернути; інакше надрукувати n.
Показати підказку
Канонічний шаблон: перевірте `err != nil`, log/return, потім використовуйте `n`.
Рішення доступне після 3 спроб
Реалізація safeDiv: if b == 0 повертає 0 і errors.New('divisione per zero'); інакше a/b і нуль.
Показати підказку
Перевірте `b == 0` ПЕРЕД поділом, щоб уникнути паніки під час виконання.
Рішення доступне після 3 спроб
Який ідіоматичний шаблон обробки помилок у Go?
v, err := f()
// poi?Підведення підсумків
error— це інтерфейс з одним методомError() string.- Канонічний шаблон:
v, err := f(); if err != nil { return err }. - Помилки збірки з
errors.New(msg)абоfmt.Errorf("ctx: %w", err). - Використовуйте
%wдля обмотування таerrors.Is/errors.Asдля перевірки ланцюга. panicлише для невиправних помилок, НЕ для звичайного потоку керування.