1 คะแนน โดย GN⁺ 2023-09-20 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Go 1.22 รุ่นถัดไปมีแผนจะแก้ไขข้อผิดพลาดที่พบบ่อยของช่วงลูป for ซึ่งก่อให้เกิดปัญหาในการใช้งานจริงในหลายบริษัท
  • ปัญหานี้เกิดขึ้นเมื่อมีการคงการอ้างอิงถึงตัวแปรของลูปไว้หลังจากสิ้นสุดการวนซ้ำ ทำให้ตัวแปรนั้นมีค่าใหม่โดยไม่ตั้งใจ
  • ปัญหานี้พบได้บ่อยทั้งในโค้ด Go แบบ concurrent และ non-concurrent และระบุรวมถึงแก้ไขได้ยาก เนื่องจากความซับซ้อนในการวิเคราะห์ว่าการอ้างอิงถึงตัวแปรนั้นยาวนานเกินช่วงการวนซ้ำหรือไม่
  • เครื่องมือที่มีอยู่ในปัจจุบันสำหรับระบุความผิดพลาดลักษณะนี้มักก่อให้เกิด false negative หรือ false positive ส่งผลให้เกิดการแก้โค้ดโดยไม่จำเป็นหรือทำให้มองข้ามปัญหาไป
  • การแก้ไขที่เสนอใน Go 1.22 จะเปลี่ยนให้ลูป for มีขอบเขตระดับลูปแทนขอบเขตระดับการวนซ้ำ ช่วยกำจัดความผิดพลาดประเภทนี้และลดความจำเป็นของเครื่องมือที่ไม่แม่นยำ
  • เพื่อคงความเข้ากันได้ย้อนหลัง semantics ใหม่จะมีผลเฉพาะกับแพ็กเกจที่อยู่ในโมดูลซึ่งประกาศ Go 1.22 ขึ้นไปในไฟล์ go.mod เท่านั้น
  • นักพัฒนาสามารถควบคุมได้ว่า semantics จะเปลี่ยนเมื่อใดในแต่ละแพ็กเกจ และโค้ดเดิมก็จะยังคงทำงานแบบปัจจุบันต่อไป
  • Go 1.21 มีตัวอย่างล่วงหน้าของการเปลี่ยนแปลงขอบเขตนี้รวมอยู่ด้วย โดยสามารถเปิดใช้งานได้ด้วยการตั้งค่า GOEXPERIMENT=loopvar ในสภาพแวดล้อม
  • การเปลี่ยนแปลงนี้ได้รับการทดสอบอย่างกว้างขวางภายใน Google แล้ว และไม่มีปัญหาที่มีการรายงานในโค้ด production
  • อย่างไรก็ตาม บางการทดสอบที่ไม่ได้ทดสอบสิ่งที่ตั้งใจไว้ตั้งแต่แรกเนื่องจากปัญหาตัวแปรลูป จำเป็นต้องได้รับการแก้ไข
  • ตัววิเคราะห์ loopclosure ใน Go 1.21 ได้รับการปรับปรุงให้ระบุและรายงานปัญหาประเภทนี้ได้ดีขึ้น เพื่อช่วยให้นักพัฒนาเตรียมพร้อมสำหรับการเปลี่ยนแปลงใน Go 1.22
  • สามารถดูข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงนี้ได้ในเอกสารการออกแบบและ FAQ

1 ความคิดเห็น

 
GN⁺ 2023-09-20
ความเห็นจาก Hacker News
  • การพูดคุยเกี่ยวกับปัญหา for loops ใน Go 1.22 โดยเน้นไปที่การใช้ตัวแปรลูปผิดพลาดภายในคลोजเชอร์
  • ปัญหาการใช้ตัวแปรลูปผิดพลาดภายในคลोजเชอร์ไม่ใช่เรื่องใหม่ และย้อนไปได้ถึงภาษา Lisp ในปี 1992
  • ทีมพัฒนาภาษา C# ก็เคยเจอปัญหานี้เช่นกัน และได้ทำการเปลี่ยนแปลงครั้งสำคัญใน C# 5.0 เพื่อแก้ไขมัน
  • Go 1.21 จะไม่คอมไพล์โค้ดที่ประกาศว่าต้องการเวอร์ชันหลัง Go 1.22 ซึ่งช่วยรับประกันว่าโค้ดที่พึ่งพาความหมายแบบใหม่จะไม่ถูกคอมไพล์ด้วยความหมายแบบเก่า
  • มีความกังวลว่าการเปลี่ยนแปลงนี้อาจทำให้โปรแกรมที่พึ่งพาพฤติกรรมปัจจุบันใช้งานไม่ได้
  • ผู้ใช้บางคนตั้งคำถามว่ามันจะทำงานอย่างไรในทางปฏิบัติ หากแพ็กเกจกำหนดเป็น 1.22 แต่ผู้ใช้คอมไพล์ด้วย 1.18
  • ยังมีคำถามเกี่ยวกับผลกระทบของการเปลี่ยนแปลงนี้ต่อการจัดสรรหน่วยความจำและประสิทธิภาพของลูป
  • ผู้ใช้บางส่วนแบ่งปันประสบการณ์ว่าเคยเจอปัญหาคล้ายกันในภาษาอื่น เช่น Python
  • การเปลี่ยนแปลงใน Go 1.22 ดูเหมือนเป็นวิธีแก้ปัญหาในไวยากรณ์ของภาษา แต่สำหรับผู้ใช้บางคนมันให้ความรู้สึกไม่ค่อยเป็นธรรมชาติ เพราะต้องรู้เวอร์ชันที่ประกาศไว้ในไฟล์หนึ่งก่อน จึงจะเข้าใจพฤติกรรมของอีกไฟล์ได้