1 คะแนน โดย GN⁺ 2025-02-15 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Go 1.24 เป็นอัปเดตอย่างเป็นทางการถัดจาก Go 1.23 ครอบคลุมการเปลี่ยนแปลงที่นักพัฒนาสัมผัสได้ทันทีอย่างกว้างขวาง ตั้งแต่ฟีเจอร์ภาษา ไปจนถึง runtime, standard library และ WebAssembly
  • ในระดับภาษา รองรับ generic type aliases อย่างเต็มรูปแบบ ทำให้ type alias สามารถกำหนดพารามิเตอร์ได้เช่นเดียวกับ defined type
  • runtime ใช้ map ที่อิง Swiss Tables ปรับปรุงการจัดสรรอ็อบเจ็กต์ขนาดเล็ก และเปลี่ยน mutex ภายใน ส่งผลให้ benchmark ตัวแทนโดยเฉลี่ยมี CPU overhead ลดลง 2–3%
  • คำสั่ง go เพิ่มโฟลว์สำหรับติดตามและรัน tool dependencies ของโมดูล และ go vet ตรวจจับข้อผิดพลาดในการประกาศที่เกี่ยวกับการทดสอบได้ดีขึ้น
  • standard library และการรองรับแพลตฟอร์มก็ขยายเพิ่มขึ้น ควรตรวจสอบ FIPS 140-3, testing.B.Loop, os.Root, runtime.AddCleanup, go:wasmexport และการ build แบบ WASI reactor/library

ขอบเขตการเปลี่ยนแปลงของ Go 1.24

  • Go 1.24 เป็น release ที่มีการปรับปรุงหลายอย่างเมื่อเทียบกับ Go 1.23 โดยดูรายการเปลี่ยนแปลงทั้งหมดได้ที่ Go 1.24 release notes
  • สามารถดาวน์โหลดเวอร์ชันใหม่ได้จากหน้าดาวน์โหลดของ Go

การเปลี่ยนแปลงของภาษา: generic type aliases

  • Go 1.24 รองรับ generic type aliases อย่างเต็มรูปแบบ
  • type alias สามารถ กำหนดพารามิเตอร์ ได้เช่นเดียวกับ defined type ทำให้ขอบเขตการสื่อความในโค้ด generic กว้างขึ้น
  • ไวยากรณ์โดยละเอียดรวมอยู่ใน language spec

การปรับปรุงประสิทธิภาพ runtime

  • ด้วยการปรับปรุง runtime ชุด benchmark ตัวแทนมี CPU overhead ลดลงโดยเฉลี่ย 2–3%
  • แกนหลักของการเปลี่ยนแปลงด้านประสิทธิภาพมี 3 อย่าง
    • implementation ใหม่ของ map ในตัวที่อิง Swiss Tables
    • การจัดสรรหน่วยความจำ สำหรับอ็อบเจ็กต์ขนาดเล็กที่มีประสิทธิภาพขึ้น
    • implementation ใหม่ของ mutex ภายใน runtime

การปรับปรุงเครื่องมือ Go

  • คำสั่ง go มีกลไกสำหรับติดตาม tool dependencies ของโมดูล
    • ใช้ go get -tool เพื่อเพิ่ม directive tool ให้โมดูลปัจจุบัน
    • ใช้ go tool [tool name] เพื่อรันเครื่องมือที่ประกาศไว้ใน directive tool
    • รายละเอียดเพิ่มเติมอยู่ในหัวข้อ go command ของ release notes
  • เพิ่ม analyzer ใหม่ test ในคำสั่งย่อย go vet
    • รายงานข้อผิดพลาดที่พบบ่อยในการประกาศ test, fuzzer, benchmark และ example ของแพ็กเกจทดสอบ
    • รายละเอียดเพิ่มเติมอยู่ในหัวข้อ vet ของ release notes

การเพิ่ม API ใน standard library และ runtime

  • standard library มีชุดกลไกใหม่ที่ช่วยให้เป็นไปตาม FIPS 140-3
    • ไม่จำเป็นต้องเปลี่ยนซอร์สโค้ดของแอปพลิเคชันเพื่อใช้กลไกใหม่สำหรับอัลกอริทึมที่ได้รับการอนุมัติ
    • รายละเอียดเพิ่มเติมอยู่ในหัวข้อ FIPS 140-3 compliance ของ release notes
  • นอกจาก FIPS 140 แล้ว ยังมีแพ็กเกจหลายตัวที่เคยอยู่ในโมดูล x/crypto ถูก提供ให้ใน standard library
  • โค้ด benchmark สามารถใช้เมธอด testing.B.Loop ได้
    • ทำการวนซ้ำ benchmark ในรูปแบบ for b.Loop() { ... }
    • สามารถใช้แทนโครงสร้างลูปทั่วไปที่ใช้ b.N เช่น for range b.N
    • วิธีนี้เร็วกว่าและมีโอกาสเกิดข้อผิดพลาดน้อยกว่า
  • type ใหม่ os.Root ช่วยให้ทำ งานกับระบบไฟล์ ที่ถูกจำกัดให้อยู่ใต้ไดเรกทอรีเฉพาะได้
  • runtime เพิ่มกลไก cleanup ใหม่ runtime.AddCleanup
    • ยืดหยุ่นและมีประสิทธิภาพกว่า runtime.SetFinalizer อีกทั้งมีโอกาสเกิดข้อผิดพลาดน้อยกว่า

การปรับปรุงการรองรับ WebAssembly

  • Go 1.24 เพิ่ม directive ใหม่ go:wasmexport ที่ทำให้โปรแกรม Go export ฟังก์ชันไปยัง WebAssembly host ได้
  • สามารถ build โปรแกรม Go เป็น WASI reactor/library ได้
  • รายละเอียดเพิ่มเติมอยู่ในหัวข้อ WebAssembly ของ release notes

คำแนะนำถัดไปและ feedback

  • รายละเอียดทั้งหมดอยู่ใน Go 1.24 release notes
  • บางหัวข้อจะกล่าวถึงเชิงลึกเพิ่มเติมในบล็อกโพสต์ต่อไป
  • หากพบปัญหา สามารถเปิด issue ได้

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

 
GN⁺ 2025-02-15
ความคิดเห็นบน Hacker News
  • ดีใจเป็นพิเศษกับ การปรับปรุง implementation ของ map ให้เร็วขึ้น และก็ดีที่ตอนนี้ text/template รองรับ range-over-func แล้ว
    Go 1.23 เพิ่ม range สำหรับชนิดฟังก์ชันเข้ามาแล้ว แต่จนถึงตอนนี้ยังใช้ใน Go template ไม่ได้

  • ชอบตรงที่มันราบรื่นจนแทบจะน่าเบื่อ

  • สงสัยว่า os.Root จะใช้กับกรณีไหน
    เท่าที่เข้าใจดูเหมือนเกี่ยวกับความปลอดภัยแบบ https://github.com/golang/go/issues/67002 แต่เพราะข้างในไม่ได้ใช้ Chroot สุดท้ายอาจมีใครหาวิธีหลุดออกไปนอก Root ได้ก็ได้

    • chroot จะมีความหมายก็ต่อเมื่อแอปพลิเคชันสามารถยืนยันได้ว่าจะทำงานอยู่ ภายในไดเรกทอรีเดียวเท่านั้น ต่อจากนี้
      อีกทั้งโปรเซสยังต้องมีสิทธิ์ superuser จึงใช้กับแอปพลิเคชันที่รันด้วยสิทธิ์ผู้ใช้ทั่วไปไม่ได้
      os.Root() ใกล้เคียงกับการคาด เข็มขัดนิรภัย ให้การทำงานกับระบบไฟล์มากกว่า เช่น จำกัดงานเกี่ยวกับแคชของแอปพลิเคชันให้อยู่ในไดเรกทอรีแคช หรือทำให้ file server ให้บริการเฉพาะไฟล์ในไดเรกทอรีแชร์ที่เหมาะสมเท่านั้น ไม่ใช่การรับประกันแน่นหนาเหมือน chroot แต่ช่วยกันการโจมตีแบบ directory traversal ง่าย ๆ ได้
    • ไม่เข้าใจว่าทำไมต้องใช้ chroot
      ถ้าใช้ร่วมกับ ฟีเจอร์ sandbox อย่าง Capsicum ก็สามารถเปิดไดเรกทอรีไว้ก่อนเข้า capability mode แล้วภายหลังใช้ os.Root เปิดไฟล์ในทรีระบบไฟล์ใต้ไดเรกทอรีที่เปิดไว้นั้นได้
  • สงสัยว่าสามารถระบุ tag ที่จะใช้ตอนติดตั้งเครื่องมือที่กำหนดด้วย directive tools ได้ไหม
    ลองแบบด้านล่างแล้ว แต่ดูเหมือนจะติดตั้งโดยไม่ใช้ tag
    go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest

  • มีบอกว่าถ้าใช้ GODEBUG=fips140=only อัลกอริทึมเข้ารหัสที่ไม่เป็นไปตาม FIPS 140-3 จะคืน error หรือ panic แต่ไม่ค่อยชอบวิธีที่ standard library ตั้งใจให้เกิด panic เท่าไร
    ยังไม่ได้ดูโค้ด แต่สงสัยว่าทำแบบนั้นเฉพาะกับฟังก์ชันที่ปัจจุบันไม่คืน error เพราะเหตุผลเรื่อง backward compatibility หรือเปล่า

    • นี่เป็นฟีเจอร์ที่จำเป็นใน สภาพแวดล้อมภาครัฐ
      ถ้าไม่ตรวจสอบตอน runtime ว่าตั้งค่า FIPS อยู่หรือไม่ ก็เสี่ยงทำให้ compliance พัง และสุดท้ายจะนำไปสู่การ audit กับการประชุมไม่รู้จบ ผมมองว่าการเกิด incident 30 นาทีจาก panic ยังดีกว่าต้องลำบากหลายวันเพื่อสร้าง control และกระบวนการตรวจสอบใหม่
    • ถ้าอย่างนั้นก็ไม่ต้องตั้ง flag นั้น
      พฤติกรรมแบบนี้มีประโยชน์กับสถานการณ์ที่ตรวจจับได้เฉพาะตอน runtime เท่านั้น แค่มี test coverage พื้นฐานก็น่าจะเห็นได้ทันที
    • ทางเลือกที่สมจริงมีแค่การคืน error แต่ error สามารถถูกจับแล้วเพิกเฉยได้
      ในสถานการณ์ที่เกี่ยวกับ การเข้ารหัส ก็ไม่แน่ใจว่านั่นเป็นสิ่งที่พึงประสงค์หรือไม่ ผมคิดว่าควรหลีกเลี่ยงระดับ warning log ถ้าเป็นเรื่องสำคัญและแก้ไขได้ก็ควรเป็น error หรือ fatal log ถ้าไม่ใช่ แค่ info log ก็พอ
    • อ่านมาว่าส่วนนี้น่าจะถูกจัดระเบียบใน Go 1.25
      https://devblogs.microsoft.com/go/go-1-24-fips-update/
    • อย่างที่คอมเมนต์พี่น้องบอก บางกรณีก็จำเป็นต้องบังคับ
      มองได้ว่าเป็นวิธีหลีกเลี่ยง bug ที่ซ่อนอยู่ คล้ายกับ "The server chose violence" [1] [2] และก็น่าคิดว่า Postel's law ทำให้ interoperability สะดุดมากแค่ไหน จุดนี้มักถูกลืมในหลายแง่มุมของการรับรอง FIPS
      [1] https://cliffle.com/blog/hubris-reply-fault/
      [2] https://news.ycombinator.com/item?id=40178652
  • ในที่สุดก็มี generic type alias แล้ว เป็นฟีเจอร์ที่ควรมีมาตั้งนาน

  • ตั้งตารอ tool flag ใหม่ที่สุดแล้ว ตอนนี้จะได้เลิกใช้ tools.go ที่ดูไม่สวยเสียที

  • ดีเลย รีลีสนี้รออยู่เพราะ GOAUTH
    หวังว่างานกับ private git repository จะยุ่งยากน้อยลง แต่พอดู go help goauth แล้วก็เหมือนจะคาดหวังมากไม่ได้