1 điểm bởi GN⁺ 2023-09-20 | 1 bình luận | Chia sẻ qua WhatsApp
  • Bản phát hành Go 1.22 sắp tới dự kiến sẽ sửa một lỗi phổ biến liên quan đến phạm vi của vòng lặp for, lỗi đã gây ra sự cố trong môi trường production ở nhiều công ty.
  • Vấn đề xảy ra khi tham chiếu đến biến vòng lặp vẫn được giữ lại sau khi lần lặp kết thúc, khiến nó mang một giá trị mới ngoài ý muốn.
  • Lỗi này phổ biến trong cả mã Go đồng bộ lẫn bất đồng bộ, và rất khó xác định cũng như khắc phục do tính phức tạp của việc phân tích xem tham chiếu đến biến có vượt ra ngoài lần lặp hay không.
  • Các công cụ hiện có để nhận diện loại sai sót này thường dẫn đến false negative hoặc false positive, gây ra các thay đổi mã không cần thiết hoặc bỏ sót vấn đề.
  • Bản sửa được đề xuất trong Go 1.22 sẽ thay đổi để vòng lặp for có phạm vi theo từng lần lặp thay vì phạm vi theo toàn bộ vòng lặp, qua đó loại bỏ kiểu sai sót này và nhu cầu về các công cụ thiếu chính xác.
  • Để duy trì khả năng tương thích ngược, ngữ nghĩa mới sẽ chỉ áp dụng cho các package nằm trong module khai báo Go 1.22 trở lên trong tệp go.mod.
  • Các nhà phát triển có thể kiểm soát thời điểm ngữ nghĩa thay đổi đối với từng package cụ thể, và mã hiện có sẽ tiếp tục hoạt động như hiện nay.
  • Go 1.21 bao gồm bản xem trước của thay đổi phạm vi này, có thể kích hoạt bằng cách thiết lập GOEXPERIMENT=loopvar trong môi trường.
  • Thay đổi này đã được thử nghiệm rộng rãi tại Google và không có vấn đề nào được báo cáo trong mã production.
  • Tuy nhiên, một số bài kiểm thử vốn không kiểm thử đúng nội dung dự định ban đầu do vấn đề biến vòng lặp sẽ cần được sửa lại.
  • Bộ phân tích loopclosure trong Go 1.21 đã được cải thiện để nhận diện và báo cáo tốt hơn loại vấn đề này, giúp các nhà phát triển chuẩn bị cho thay đổi trong Go 1.22.
  • Có thể tìm thêm thông tin chi tiết về thay đổi này trong tài liệu thiết kế và phần FAQ.

1 bình luận

 
GN⁺ 2023-09-20
Ý kiến trên Hacker News
  • Thảo luận về vấn đề for loops trong Go 1.22, tập trung vào việc sử dụng sai biến vòng lặp trong closure
  • Vấn đề sử dụng sai biến vòng lặp trong closure không phải là mới, mà đã có từ ngôn ngữ Lisp năm 1992
  • Nhóm ngôn ngữ C# cũng từng đối mặt với vấn đề này và đã thực hiện một thay đổi quan trọng trong C# 5.0 để giải quyết nó
  • Go 1.21 không biên dịch mã khai báo sau Go 1.22, qua đó đảm bảo mã phụ thuộc vào ngữ nghĩa mới sẽ không bị biên dịch theo ngữ nghĩa cũ
  • Có lo ngại rằng thay đổi này có thể làm hỏng các chương trình đang phụ thuộc vào hành vi hiện tại
  • Một số người dùng đặt câu hỏi về việc thực tế sẽ hoạt động thế nào nếu package cố định ở 1.22 nhưng người dùng lại biên dịch bằng 1.18
  • Cũng có câu hỏi về tác động của thay đổi này tới cấp phát bộ nhớ và hiệu năng vòng lặp
  • Một số người dùng chia sẻ rằng họ từng gặp vấn đề tương tự trong các ngôn ngữ khác như Python
  • Thay đổi trong Go 1.22 có vẻ là một cách giải quyết vấn đề của cú pháp ngôn ngữ, nhưng với một số người dùng, nó không trực quan vì cần biết phiên bản được khai báo trong một tệp để hiểu hành vi của tệp khác