Giới thiệu về gói Go giúp giảm boilerplate lỗi
Go là một ngôn ngữ lập trình tuyệt vời, nhưng nhiều lập trình viên thường phải viết lại đoạn mã kiểm tra lỗi lặp đi lặp lại. Thông thường, đoạn mã này trông như sau:
go
if err != nil {
return nil, err
}
Việc này có thể dẫn đến việc viết thêm hàng chục dòng mã chỉ để xử lý lỗi trong một phương thức. Với ý tưởng muốn giảm thiểu mã boilerplate này, tôi đã phát triển một gói Go có tên là to, giúp dễ dàng hơn trong việc xử lý lỗi mà không cần viết lại nhiều lần.
Mục tiêu
Mục tiêu của tôi là triển khai một toán tử ống chuyển tiếp (forward pipe operator) hoặc bind monad. Điều này cho phép chúng ta nối chuỗi nhiều phương thức, trong đó đầu vào của phương thức tiếp theo là đầu ra của phương thức trước đó. Khi gặp lỗi đầu tiên, gói sẽ trả về lỗi đó và giá trị mặc định cho kết quả mong đợi. Nếu không có lỗi nào, nó sẽ trả về kết quả của phép toán cuối cùng.
Vấn đề
Trong C#, việc sử dụng ống chuyển tiếp khá đơn giản. Tôi đã tạo một phương thức mở rộng trên đối tượng cơ sở, cho phép bất kỳ đối tượng nào gọi .Pipe(methodName). Điều đó có nghĩa là bạn có thể gọi 1.Pipe(Increment).Pipe(Increment) và nhận được giá trị 3.
Mặc dù Go không phải là ngôn ngữ lập trình hướng đối tượng, nhưng nó vẫn hỗ trợ các phương thức. Tôi đã nghĩ đến việc tạo một struct gọi là Chain với một phương thức .Bind nhận vào phương thức tiếp theo và trả về một đối tượng Chain mới. Tuy nhiên, Go không hỗ trợ generics trên các phương thức, điều này làm cho việc tạo ra một struct với kiểu không ràng buộc trở nên khó khăn.
Ý tưởng tiếp theo của tôi là tạo một hàm Compose[T, U, V any](func(T)(U, error), fn2(U) (V, error)) func(T) (V, error). Hàm này cho phép người dùng liên kết các hàm bằng cách gọi Bind(fn1, Bind(fn2, fn3)). Tuy nhiên, cú pháp này khá phức tạp và có một chút chi phí về số lần gọi hàm.
Sử dụng tham số biến và type assertions cũng có triển vọng, nhưng tôi không muốn sử dụng reflection vì nó cũng có chi phí cao.
Giải pháp tạm ổn
Cuối cùng, giao diện cho gói này là to.Bind3(input, fn1, fn2, fn3). Chỉ cần thêm một ký tự và chi phí duy nhất là việc gọi hàm. Gói này cung cấp các biến thể từ 1 đến 32 tham số.
Tôi đã cân nhắc sử dụng bind.Three vì nó tạo thành một câu tốt hơn, nhưng tôi nghĩ rằng điều đó có thể làm gián đoạn dòng suy nghĩ của lập trình viên nếu họ phải nghĩ cách đánh vần một từ thay vì chỉ cần nhập số mới trên bàn phím.
Ví dụ thực tế
Trước khi sử dụng gói to, mã của bạn có thể trông như sau:
go
// Trước khi
func SaveWithoutBind(input string) (path, error) {
sanitized, err := sanitize(input)
if err != nil {
return "", err
}
cased, err := correctCasing(sanitized)
if err != nil {
return "", err
}
queried, err := getExtraInfo(cased)
if err != nil {
return "", err
}
path, err := submit(queried)
if err != nil {
return "", err
}
return path, nil
}
// Sau khi
func SaveWithBind(input string) (path, error) {
return to.Bind4(input,
sanitize,
correctCasing,
getExtraInfo,
submit)
}
Như bạn có thể thấy, việc sử dụng gói to giúp mã ngắn gọn và rõ ràng hơn rất nhiều.
Cách cài đặt
Để cài đặt gói này, bạn chỉ cần chạy lệnh sau:
bash
go get github.com/ivypuckett/to@v1
Tài nguyên tham khảo
Những điểm cần lưu ý
- Khi sử dụng gói này, hãy chú ý đến cách bạn tổ chức mã của mình để tận dụng tối đa lợi ích mà nó mang lại.
- Đảm bảo rằng bạn đã cài đặt Go và các phụ thuộc cần thiết trước khi bắt đầu.
FAQ
1. Gói này có tương thích với các phiên bản Go cũ không?
Gói được thiết kế để hoạt động tốt với các phiên bản Go mới nhất. Hãy kiểm tra tài liệu để biết thêm chi tiết.
2. Có thể sử dụng gói này trong các dự án lớn không?
Chắc chắn rồi! Gói này giúp tổ chức mã của bạn tốt hơn và giảm thiểu lỗi trong quá trình phát triển.
3. Làm thế nào để đóng góp cho gói này?
Bạn có thể mở pull request trên repo GitHub của chúng tôi với các cải tiến hoặc báo cáo lỗi.
Kết luận
Gói to là một công cụ hữu ích giúp lập trình viên Go giảm thiểu mã boilerplate trong việc xử lý lỗi. Bằng cách sử dụng toán tử ống chuyển tiếp, bạn có thể tổ chức mã của mình một cách hợp lý hơn. Hãy thử nghiệm với gói này và chia sẻ trải nghiệm của bạn với cộng đồng!