[MẸO] Tránh Sử dụng init() trong Go Trừ Khi Cần Thiết
By JoeVu, at: 11:08 Ngày 11 tháng 9 năm 2024
Thời gian đọc ước tính: __READING_TIME__ minutes
![[TIPS] Avoid Using init() in Go Unless Necessary](/media/filer_public_thumbnails/filer_public/ba/65/ba65941e-134e-43ec-b905-12ad67dc2502/golang_-_init_function.png__1500x900_crop_subsampling-2_upscale.png)
![[TIPS] Avoid Using init() in Go Unless Necessary](/media/filer_public_thumbnails/filer_public/ba/65/ba65941e-134e-43ec-b905-12ad67dc2502/golang_-_init_function.png__400x240_crop_subsampling-2_upscale.png)
Tránh Sử Dụng init()
trong Go Trừ Khi Thực Sự Cần Thiết
Hàm init()
trong Go là một hàm đặc biệt được tự động thực thi trước hàm main()
, và thậm chí trước bất kỳ mã nào khác trong package. Mặc dù nó có thể hữu ích, nhưng việc sử dụng quá nhiều có thể làm cho mã của bạn khó theo dõi và bảo trì hơn. Dưới đây là lý do tại sao bạn nên tránh sử dụng init()
trừ khi hoàn toàn cần thiết.
Tại Sao init()
Có Thể Gây Vấn Đề
-
Logic Ẩn: Vì
init()
được thực thi tự động, nên nó có thể giới thiệu hành vi ẩn không rõ ràng từ luồng chính của mã. Điều này có thể làm cho việc gỡ lỗi và hiểu mã trở nên khó khăn hơn, đặc biệt là đối với các dự án lớn hơn.
-
Thứ Tự Thực Thi: Go không đảm bảo thứ tự thực thi các hàm
init()
trên các package khác nhau. Nếu nhiều package có các hàminit()
, điều này có thể dẫn đến hành vi không thể đoán trước, làm cho chương trình khó lập luận hơn.
-
Kiểm Thử Phức Tạp: Nếu logic thiết lập quan trọng bị ẩn bên trong
init()
, việc mô phỏng hoặc bỏ qua trong quá trình kiểm thử có thể khó khăn. Điều này có thể dẫn đến các bài kiểm thử được liên kết chặt chẽ, khó viết và bảo trì hơn.
Khi Nào Sử Dụng init()
Bất chấp những nhược điểm tiềm tàng, có những trường hợp sử dụng hợp lệ cho init()
:
-
Cấu Hình Cấp Package: Nếu một package cần khởi tạo một số trạng thái hoặc cấu hình trước khi được sử dụng (ví dụ: thiết lập một trình ghi nhật ký toàn cục),
init()
có thể hữu ích. Tuy nhiên, hãy đảm bảo rằng việc thiết lập này là cần thiết và không thể được xử lý trongmain()
hoặc ở nơi khác.
-
Đăng Ký Thành Phần: Một số package, đặc biệt là những package cung cấp chức năng mở rộng như plugin hoặc middleware, sử dụng
init()
để đăng ký các thành phần. Điều này là chấp nhận được, nhưng hãy cố gắng ghi lại hành vi này rõ ràng để tránh nhầm lẫn.
Ví Dụ Sử Dụng init()
package main
import (
"log"
"os"
)
func init() {
// Thiết lập một trình ghi nhật ký toàn cục
log.SetOutput(os.Stdout)
log.Println("Logger initialized")
}
func main() {
log.Println("This is the main function")
}
Trong ví dụ này, init()
được sử dụng để thiết lập một trình ghi nhật ký toàn cục trước khi hàm main()
chạy. Mặc dù đây là một trường hợp sử dụng hợp lệ, hãy xem xét liệu việc thiết lập này có thể được thực hiện một cách rõ ràng trong main()
để có độ rõ ràng tốt hơn.
Đọc thêm: https://www.digitalocean.com/community/tutorials/understanding-init-in-go