ทำไมบทความนี้ครอบคลุมสี่ minor versions พร้อมกัน

Go releases ออกทุกหกเดือน การอ่านสี่ชุดของ release notes ติดต่อกันไม่ใช่วิธีที่ใครอยากใช้บ่ายบ่าย แต่ถ้าคุณรัน Go ใน production คุณต้องรู้ว่าอะไรเปลี่ยน

บทความนี้ครอบคลุม Go 1.22 ถึง Go 1.26 — เวอร์ชันที่ออกระหว่างต้นปี 2024 ถึงต้นปี 2026 นั่นคือสองปีของ language evolution ในที่เดียว

Go 1.22: For Loop Changes Everything

กุมภาพันธ์ 2024 การเปลี่ยนแปลงที่มีผลกระทบมากที่สุดใน Go 1.22 ไม่ใช่ package ใหม่หรือ compiler optimization แต่เป็น fix เกี่ยวกับวิธีที่ for loops จัดการ variables

ก่อน Go 1.22, โค้ดนี้มี bug แบบ subtle:

var funcs []func()
for i := range 10 {
    funcs = append(funcs, func() {
        fmt.Println(i)
    })
}
for _, f := range funcs {
    f() // prints 9 ten times, not 0-9
}

ทุก closure capture variable เดียวกัน i เมื่อคุณเรียก functions, i คือ 9 bug นี้เคยชน dev ทุกคนอย่างน้อยหนึ่งครั้ง

Go 1.22 เปลี่ยนสิ่งนี้ แต่ละ loop iteration สร้าง variables ใหม่ closures capture different variables โค้ดทำงานตามที่คุณคาดหวัง — พิมพ์ 0 ถึง 9

ทีม Go ให้ transition tooling เพื่อให้คุณตรวจจับ code ที่พึ่งพา old behavior go vet จับ pattern นั้นได้ แต่ fix เอง clean: ถ้าโค้ดของคุณดูถูกต้อง มันก็น่าจะถูกต้อง

Range over integers เป็น addition ที่ notable อีกอย่าง:

for i := range 10 {
    fmt.Println(10 - i)
}

เรียบง่าย, ชัดเจน, กำจัด common pattern for i := 0; i < n; i++ ไม่จำเป็นอีกต่อไป

Go 1.26: Self-Referential Generics Fix

กุมภาพันธ์ 2026 เวอร์ชันล่าสุดที่ stable และการเปลี่ยนแปลงที่สำคัญที่สุดสำหรับใครก็ตามที่สร้าง generic data structures

type Tree[T any] struct {
    Value T
    Left  *Tree[T]
    Right *Tree[T]
}

ก่อน Go 1.26, นี่ illegal generic type ไม่สามารถอ้างถึงตัวเองใน type parameter list คุณต้อง workaround ด้วย non-generic node types หรือ interface tricks

Go 1.26 ยกเลิก restriction นี้ Generic types ตอนนี้สามารถอ้างถึงตัวเองได้ ซึ่งหมายความว่า linked lists, trees, และ graph nodes สามารถเป็น properly generic โดยไม่ต้องมี wrapper types

new() builtin ก็ได้รับความยืดหยุ่นมากขึ้น:

// ก่อน: ต้องการ statement แยก
n := new(int)
*n = 42

// หลัง: expression form
n := new(int)
*n = new(42) // new สามารถรับ expression ได้

ผลกระทบในทางปฏิบัติ: การทำงานกับ optional fields ใน serialization (เช่น encoding/json กับ pointer fields) กลายเป็น clean มากขึ้น

Runtime Improvements ที่ควรรู้

Go 1.26 shipped garbage collector ใหม่ที่ลด pause times โดยการแยกระหว่าง “must-collect” และ “may-collect” work ผลลัพธ์: pause ที่น้อยกว่าสำหรับ workloads ที่ sensitive ต่อ latency

Faster cgo calls ได้ landing ใน release เดียวกัน ถ้าคุณเรียก C จาก Go, overhead ลดลงอย่างมีนัยสำคัญ ไม่ใช่การเปลี่ยนแปลงสำหรับทุกคน แต่สำหรับคนที่ต้องการ มันสำคัญ

Heap base address randomization มาเป็น security hardening measure ASLR สำหรับ Go heaps, ทำให้ exploitation ยากขึ้น

ยังมี experimental goroutine leak profiler go tool trace ตอนนี้สามารถ identify where goroutines are leaking ถ้าคุณเคยมี service ที่ค่อยๆ accumulate goroutines จนมันล่ม ที่นี้คือ debugging tool ที่คุณรอคอย

อะไรไม่ได้เปลี่ยน

Go’s philosophy คงเดิมข้ามทุกสี่ releases: maintain compatibility, improve toolchain, หลีกเลี่ยง language complexity

ไม่มี syntax additions ที่ significant ไม่มี major paradigm shifts language ยังเล็ก, ยัง readable, ยังออกแบบสำหรับ teams

นี่เป็น feature หรือ limitation ขึ้นอยู่กับว่าคุณเปรียบเทียบกับอะไร Go ไม่มี expressiveness ของ Rust’s traits หรือ polymorphism ของ Haskell’s type classes แต่ก็ไม่มี cognitive overhead ของการเข้าใจ features นั้น

The Upgrade Math

Go 1.26 ต้องการ Go 1.22 หรือ newer เพื่อ build ถ้าคุณอยู่บน version เก่า คุณไม่ได้ security patches

for loop fix เพียงอย่างเดียวคุ้มค่าอัพเกรด generics improvement สำคัญถ้าคุณเขียน data structures GC improvements สำคัญถ้าคุณสนใจ tail latency

ต้นทุน: testing โค้ดของคุณกับ version ใหม่ ประโยชน์: ง่ายต่อการ reason about, fewer surprises, better performance

สำหรับ most teams, math ง่าย อยู่ current


ถัดไป: practical Go project structure — วิธีจัด Go application ที่จะยัง make sense ในอีกสองปี