เปิดตัว Go 1.24
(go.dev)- 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
- implementation ใหม่ของ
การปรับปรุงเครื่องมือ Go
- คำสั่ง
goมีกลไกสำหรับติดตาม tool dependencies ของโมดูล- ใช้
go get -toolเพื่อเพิ่ม directivetoolให้โมดูลปัจจุบัน - ใช้
go tool [tool name]เพื่อรันเครื่องมือที่ประกาศไว้ใน directivetool - รายละเอียดเพิ่มเติมอยู่ในหัวข้อ 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 - วิธีนี้เร็วกว่าและมีโอกาสเกิดข้อผิดพลาดน้อยกว่า
- ทำการวนซ้ำ benchmark ในรูปแบบ
- 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 ความคิดเห็น
ความคิดเห็นบน 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 และกระบวนการตรวจสอบใหม่
พฤติกรรมแบบนี้มีประโยชน์กับสถานการณ์ที่ตรวจจับได้เฉพาะตอน runtime เท่านั้น แค่มี test coverage พื้นฐานก็น่าจะเห็นได้ทันที
ในสถานการณ์ที่เกี่ยวกับ การเข้ารหัส ก็ไม่แน่ใจว่านั่นเป็นสิ่งที่พึงประสงค์หรือไม่ ผมคิดว่าควรหลีกเลี่ยงระดับ warning log ถ้าเป็นเรื่องสำคัญและแก้ไขได้ก็ควรเป็น error หรือ fatal log ถ้าไม่ใช่ แค่ info log ก็พอ
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แล้วก็เหมือนจะคาดหวังมากไม่ได้