Xử lý lỗi
Ngôn ngữ Go áp dụng một cơ chế xử lý lỗi độc đáo. Khác với các ngôn ngữ khác sử dụng cơ chế bắt ngoại lệ try-catch, Go chọn cách xử lý lỗi như các giá trị trả về thông thường, thiết kế này khiến việc xử lý lỗi trở nên rõ ràng và có thể kiểm soát hơn. Đồng thời, Go còn cung cấp các cơ chế như defer, panic, recover để xử lý các tình huống đặc biệt.
Cơ chế cốt lõi
Xử lý lỗi trong Go chủ yếu được cấu thành từ các cơ chế cốt lõi sau:
Từ khóa defer
defer là một từ khóa rất phổ biến trong ngôn ngữ Go, dùng để trì hoãn thực thi lời gọi hàm. Các đặc điểm chính:
- Vào trước ra sau: nhiều defer thực thi theo thứ tự ngược lại với thứ tự khai báo
- Quản lý tài nguyên: thường dùng cho các thao tác dọn dẹp tài nguyên như đóng file, giải phóng mutex
- Tham số tính toán trước: tham số của defer đã được xác định khi khai báo
defer tồn tại dưới hình thức danh sách liên kết trong runtime, liên kết trực tiếp với goroutine G, là công cụ quan trọng để Go thực hiện quản lý tài nguyên tao nhã.
Lỗi panic
panic là một hàm built-in của Go, dùng để xử lý các tình huống lỗi không thể phục hồi:
- Chủ động kích hoạt: nhà phát triển có thể thủ công gọi panic để chương trình thoát
- Bị động kích hoạt: lỗi runtime (như truy cập con trỏ nil) sẽ tự động kích hoạt panic
- Kết hợp với recover: thông qua recover có thể bắt panic, thực hiện hiệu quả bắt ngoại lệ tương tự
panic tương ứng với cấu trúc _panic trong runtime, kết hợp với defer có thể thực hiện phục hồi lỗi tao nhã.
Lỗi con trỏ nil
Lỗi con trỏ nil là một trong những lỗi phổ biến nhất trong phát triển Go:
- Phán đoán nil kiểu interface: phán đoán nil kiểu interface cần đặc biệt chú ý
- Khẳng định kiểu: khẳng định kiểu đối với interface nil sẽ kích hoạt panic
- Gọi phương thức: gọi phương thức đối với con trỏ nil có thể kích hoạt panic
Hiểu ngữ nghĩa của nil trong Go và cách xử lý đúng là then chốt để viết code Go mạnh mẽ.
Khuyến nghị sử dụng
- Ưu tiên sử dụng giá trị trả về lỗi: đối với lỗi có thể dự kiến, sử dụng giá trị trả về error thay vì panic
- Sử dụng defer hợp lý: sử dụng defer ở đầu hàm để đảm bảo giải phóng tài nguyên, tránh bỏ sót
- Thận trọng khi sử dụng recover: recover nên được sử dụng cho các tình huống thực sự cần phục hồi, không nên dùng như cách xử lý lỗi thông thường
- Chú ý phán đoán nil: đặc biệt là phán đoán nil kiểu interface, cần hiểu cấu trúc底层 của nó
Trình tự học
Khuyến nghị học theo trình tự sau:
- Trước học từ khóa defer, hiểu nguyên lý thực thi trì hoãn
- Sau học lỗi panic, hiểu cơ chế làm việc của panic và recover
- Cuối cùng học lỗi con trỏ nil, nắm vững cách xử lý nil đúng
