Chuyển đến nội dung chính
Mô-đun 2 · Bài học 5 trong tổng số 510/50 trong khóa học~12 min
Bài học theo mô-đun (5/5)

Lỗi: mẫu `if err != nil`

Trong Go, lỗi là giá trị, không phải ngoại lệ. Một chức năng có thể thất bại trả về lỗi ở dạng giá trị cuối cùng và người gọi sẽ kiểm tra lỗi đó một cách rõ ràng. Nó rõ ràng, có thể dự đoán được, dễ kiểm tra - giá là dài dòng hơn một chút.

Giao diện error

error là một giao diện nhỏ được tích hợp trong ngôn ngữ:

Go
type error interface {
    Error() string
}

Bất kỳ loại nào triển khai Error() string đều là error.

Mẫu cơ bản

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

Bạn sẽ thấy điều này hàng nghìn lần: đó là mật mã thành ngữ cho mọi cuộc gọi sai lầm. Đừng cảm thấy tội lỗi về sự lặp lại - đó là một đặc điểm, không phải một lỗi.

Lỗi xây dựng: errors.New và fmt.Errorf

Go
import (
    "errors"
    "fmt"
)

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

fmt.Errorf hoàn hảo khi bạn muốn đưa các biến vào tin nhắn.

Gói bằng %w

Để tuyên truyền lỗi khi thêm ngữ cảnh mà KHÔNG làm mất bản gốc:

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

%w "bọc" lỗi ban đầu, có thể khôi phục sau bằng errors.Is (bình đẳng cho trọng điểm) hoặc errors.As (đối với loại bê tông):

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

Lỗi trọng điểm

Đây là các lỗi được xuất dưới dạng biến, được sử dụng để so sánh với 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 và recover (xem trước)

panic tồn tại trong Go nhưng được dành riêng cho các lỗi không thể khôi phục (ví dụ: lỗi, bất biến bị vi phạm), không dành cho luồng điều khiển thông thường. Chúng ta sẽ đi sâu hơn vào mô-đun Hàm với defer/recover. Hiện tại: không sử dụng tại chỗ của mẫu if err != nil.

Hãy thử nó

tập thể dục#go.m2.l5.e1
Nỗ lực: 0Đang tải…

Xử lý lỗi từ strconv.Atoi: if err != nil, in ra và quay lại; nếu không thì in n.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

Mẫu chuẩn: kiểm tra `err != nil`, log/return, sau đó sử dụng `n`.

Giải pháp khả dụng sau 3 lần thử

tập thể dục#go.m2.l5.e2
Nỗ lực: 0Đang tải…

Triển khai safeDiv: if b == 0 return 0 và một lỗi.New('divione per zero'); ngược lại là a/b và nil.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

Kiểm tra `b == 0` TRƯỚC phép chia để tránh tình trạng hoảng loạn trong thời gian chạy.

Giải pháp khả dụng sau 3 lần thử

Quiz#go.m2.l5.e3
Sẵn sàng

Mẫu thành ngữ nào để xử lý lỗi trong Go?

Go
v, err := f()
// poi?
Tùy chọn trả lời

Tóm tắt lại

  • error là giao diện có một phương thức Error() string.
  • Mẫu chuẩn: v, err := f(); if err != nil { return err }.
  • Tạo lỗi với errors.New(msg) hoặc fmt.Errorf("ctx: %w", err).
  • Sử dụng %w để quấn và errors.Is / errors.As để kiểm tra xích.
  • panic chỉ dành cho các lỗi không thể phục hồi, KHÔNG dành cho luồng điều khiển thông thường.