มีประเด็นน่าสนใจที่จะถูกเปลี่ยนแปลงใน go1.22 ที่จะมาถึงนี้เรื่องนึง สามารถดูอ้างอิงได้ที่นี่ https://github.com/golang/go/issues/60078
โดยเนื้อหาคร่าวๆคือ เรื่อง scope ของตัวแปรที่เราสร้างใน loop เช่น
func TestAllEven(t *testing.T) {
testCases := []int{0, 2, 4, 6}
for _, v := range testCases {
t.Run("sub", func(t *testing.T) {
t.Parallel()
if v&1 != 0 {
t.Fatal("odd v", v)
}
})
}
}
ใน proposal บอกว่าเทสนี้ ความจริงอยากทดสอบว่าตัวเลขในลิสต์ 0,2,4,6 ทั้งหมดนี้ เป็นเลขคู่หรือไม่ ซึ่งถ้าพบเลขคี่ในลิสต์มันจะพิพม์ออกมาว่า odd x
แทนที่ x ด้วยเลขคี่นั้นๆ
แต่ในปัจจุบัน go จะสร้าง instance ของ v เพียง 1 instance ต่อ loop ทั้งหมด นั่นหมายความว่า เมื่อเรารันเทสนี้ มันจะเทสที่เลข 6 เลขเดียวทั้ง 4 loop เนื่องจากเราสั่งให้มันรันแบบ parallel
โดย proposal นี้จะทำการแก้ไขให้มันสร้าง instance ใหม่ในทุกๆ iteration แทนที่จะสร้างเพียงแค่ 1 instance ให้ทุกๆ iteration ซึ่งจะมีผลทำให้เมื่อเราเอาเทสนี้ไปรันใน g1.22 มันจะสามารถเช็คเลขครบทุกตัว ตั้งแต่ 0, 2, 4 และ 6 ได้ตามที่เราคาดหวัง
ทีนี้ก็มีคนเอา code อีกชุดนึงมาเสนอว่าถ้าเป็นแบบนี้ล่ะ ใน go1.22 มันจะเปลี่ยนไปเป็นอย่างไร อ้างอิงจาก https://twitter.com/go100and1/status/1657230061777592320
package main
func main() {
for counter, i := 0, 0; i < 3; i++ {
defer func() {
counter++
print(counter)
}()
}
}
จากโค้ดชุดนี้เมื่อนำมารัน จะได้ผลลัพธ์ 123
เนื่องจาก counter ถูกสร้างเพียง 1 instance สำหรับทุก iteration แต่เมื่อเรานำโค้ดนี้ไปรันใน go1.22 มันจะได้ผลลัพธ์เป็น 111
แทน
โดยการเปลี่ยแปลงนี้น่าจะ apply เฉพาะโค้ดที่ระบุ Go version ที่ใหม่พอ (เดาว่า g0 1.22) ไม่งั้นอาจจะกระทบโค้ดเก่าๆของเราเยอะพอสมควรเลยดีเดียวครับ
Top comments (1)
@pallat รหัสอร่อย :)