1 poin oleh GN⁺ 2 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Rilis ini meningkatkan literal struct dan inferensi tipe dengan berfokus pada metode generik, serta menambahkan fitur-fitur praktis di seluruh pustaka standar, runtime, dan toolchain
  • Dengan alokasi memori khusus ukuran, biaya beberapa alokasi di bawah 80 byte berkurang hingga 30%, dan pada program yang intensif alokasi diharapkan ada peningkatan performa sekitar 1% dengan kenaikan biner sekitar 60KB
  • encoding/json/v2 kini tersedia secara resmi dan encoding/json lama juga secara internal memakai v2, sementara paket UUID standar dan tanda tangan ML-DSA berbasis FIPS 204 ikut ditambahkan
  • Profil goroutineleak, label pprof pada traceback, synctest.Sleep untuk waktu virtual, dan server uji HTTP di memori membuat diagnostik dan pengujian konkurensi jadi lebih mudah
  • Kanal timer yang tidak dibuffer, pengosongan otomatis body respons HTTP, dan pembatasan //go:linkname yang diperketat dapat memengaruhi kode lama, jadi perlu pemeriksaan kompatibilitas sebelum beralih ke Go 1.27

Bahasa dan sistem tipe

  • Fitur utama Go 1.27, metode generik, dapat mendeklarasikan parameter tipenya sendiri yang independen dari receiver
    • Sebelumnya, hanya fungsi tingkat atas yang bisa generik sehingga operasi yang melekat pada tipe pun harus ditulis sebagai fungsi paket
    • Operasi seperti Box[T].Map[U] yang mengembalikan tipe elemen berbeda dari input kini bisa didefinisikan sebagai metode
    • Interface tetap tidak dapat mendeklarasikan metode dengan parameter tipe, dan juga tidak bisa diimplementasikan dengan metode generik
  • Key literal struct kini dapat memakai bukan hanya nama field tingkat atas, tetapi juga pemilih field yang valid
    • Field yang dipromosikan dari struct embed kini bisa diinisialisasi langsung seperti User{ID: 7}
  • Inferensi tipe fungsi diperluas hingga mencakup konversi dan literal komposit
    • Seperti []func([]int) int{first, last}, argumen tipe fungsi generik diinferensikan dari tipe fungsi yang diharapkan
    • Sebelumnya harus diinstansiasi langsung seperti first[int], last[int]

Runtime dan performa

  • Kompiler memanggil rutin alokasi khusus ukuran untuk mengurangi biaya beberapa alokasi memori di bawah 80 byte hingga 30%
    • Peningkatan performa keseluruhan pada program nyata yang intensif alokasi diperkirakan sekitar 1%
    • Tidak perlu perubahan kode, tetapi ukuran biner bertambah sekitar 60KB terlepas dari beban kerja
    • Bisa dinonaktifkan dengan GOEXPERIMENT=nosizespecializedmalloc, tetapi opsi ini dijadwalkan dihapus pada Go 1.28
  • Ditambahkan tiga optimisasi kompiler baru yang aktif secara default
    • Known bits data-flow pass yang melacak bit yang pasti 0 atau 1 pada suatu nilai untuk menghapus operasi redundan
    • Loop-invariant code motion yang memindahkan perhitungan yang tidak berubah selama iterasi ke luar loop
    • switch yang memenuhi syarat dikompilasi menjadi tabel lookup termasuk fallthrough
  • GOEXPERIMENT=mapsplitgroup yang masih eksperimental mengubah tata letak memori grup map dari KVKVKVKV menjadi KKKKVVVV, dan default-nya nonaktif
  • Linker memindahkan type descriptor dan itab ke seksi .go.type khusus serta menghapus typelinks dan itablinks
    • Karena reflect.typelinks kini mengembalikan tipe alih-alih offset, pustaka yang mengakses simbol ini lewat //go:linkname bisa terdampak

Diagnostik goroutine dan profiling

  • Modul dengan go.mod Go 1.27 atau lebih baru menampilkan label runtime/pprof pada header goroutine di traceback
    • Konteks seperti {request: 42} yang ditempelkan dengan pprof.Do akan muncul di dump crash, SIGQUIT, dan output runtime.Stack
    • GODEBUG=tracebacklabels=0 tetap bisa digunakan agar label sensitif tidak terekspos di traceback
  • Detektor kebocoran goroutine yang merupakan fitur eksperimental di Go 1.26 kini dipromosikan menjadi profil resmi goroutineleak
    • Ia menjalankan GC untuk menemukan goroutine yang tidak akan pernah bisa maju lagi, seperti yang tertahan di channel atau mutex, lalu mencetak stack-nya
    • Di layanan, data bisa dikumpulkan lewat endpoint /debug/pprof/goroutineleak tanpa perlu GOEXPERIMENT

Kriptografi dan pengenal

  • Paket baru crypto/mldsa mengimplementasikan tanda tangan pasca-kuantum ML-DSA dari FIPS 204
    • Tiga set parameter MLDSA44, MLDSA65, MLDSA87 menukar ukuran kunci/tanda tangan dengan tingkat keamanan
    • ML-DSA juga ditambahkan ke kunci/tanda tangan crypto/x509 dan metode tanda tangan TLS 1.3 di crypto/tls
  • Paket baru uuid di pustaka standar menghasilkan dan mem-parsing UUID RFC 9562 dengan bilangan acak yang aman secara kriptografis
    • uuid.New() memilih metode yang cocok untuk penggunaan umum, NewV4() membuat acak murni, dan NewV7() membuat UUID berurutan menurut waktu pembuatan
    • UUID yang berbasis komponen acak bersifat comparable sehingga bisa langsung memakai ==
    • UUID v7 yang terurut waktu cocok untuk key database

JSON dan API pemrosesan data

  • encoding/json/v2 dan encoding/json/jsontext level rendah kini tersedia tanpa GOEXPERIMENT=jsonv2
    • encoding/json v1 yang lama juga secara internal memakai implementasi v2
    • Perilaku lama dipertahankan kecuali beberapa frasa pesan galat, jadi migrasi tidak diperlukan
    • Jika ada masalah kompatibilitas, GOEXPERIMENT=nojsonv2 dapat memulihkan implementasi v1 asli
    • Demi performa, v2 tidak mengurutkan key map secara default, jadi untuk pengujian yang memerlukan output stabil perlu menetapkan json.Deterministic
  • strings.CutLast dan bytes.CutLast membagi nilai berdasarkan pemisah terakhir
    • Jika tidak ada pemisah, mengembalikan seluruh input, bagian belakang kosong, dan false
  • hash/maphash generik Hasher[T] mendefinisikan strategi hash dan kesetaraan suatu nilai secara bersamaan
    • Nilai yang setara wajib memiliki hash yang sama
    • ComparableHasher[T] disediakan untuk tipe comparable, dan strategi kustom seperti string yang mengabaikan huruf besar-kecil juga bisa diimplementasikan
  • math/big.Int.Divide menghitung hasil bagi dan sisa sekaligus sambil menerapkan mode pembulatan eksplisit di antara Trunc, Floor, Round, Ceil
    • Karena sisa juga berubah sesuai mode pembulatan, ini melengkapi keterbatasan pemotongan ke arah nol pada Quo dan Mod lama untuk kode finansial dan numerik
  • math/rand/v2.(*Rand).N menghasilkan bilangan acak terbatas rentang untuk tipe integer atau duration dari sumber *Rand miliknya sendiri

SIMD portabel

  • Paket eksperimental simd menyediakan API SIMD yang independen dari ukuran vektor dan diaktifkan dengan GOEXPERIMENT=simd
    • Di lingkungan yang didukung, ini dikompilasi menjadi instruksi vektor perangkat keras yang nyata; jika tidak, digantikan dengan emulasi Go murni
    • Jumlah lane pada tipe seperti Float32s tidak tetap dan mengikuti lebar perangkat keras tiap mesin
  • Pustaka standar sudah menggunakan intrinsic internal simd/archsimd
    • MemHash32, MemHash64, StrHash pada map Swiss Table diimplementasikan ulang dengan basis SIMD baru

Pengujian deterministik

  • testing/synctest.Sleep menjalankan waktu virtual dan menunggu sampai semua goroutine stabil dalam satu langkah
    • Di dalam bubble synctest, waktu nyata tidak berjalan sehingga menunggu 2 detik pun selesai seketika
    • Ini menggantikan kode berulang dari kombinasi time.Sleep dan synctest.Wait
  • httptest.NewTestServer menjalankan server dengan jaringan virtual di memori alih-alih port TCP nyata
    • srv.Client() terhubung langsung ke handler melalui pipe internal proses
    • Karena dibersihkan otomatis dengan t.Cleanup, defer srv.Close() tidak diperlukan
    • Bila digabungkan dengan testing/synctest, round-trip HTTP juga bisa diuji dengan cepat dan deterministik di waktu virtual

Jaringan dan perubahan kompatibilitas

  • Channel yang dikembalikan time.After, time.NewTimer, time.NewTicker, dan lainnya kini selalu berupa channel sinkron tanpa buffer
    • Pengaturan GODEBUG asynctimerchan yang dulu memulihkan perilaku buffer lama telah dihapus
  • Pada HTTP/1, http.Response.Body.Close membaca body yang belum dibaca hingga batas konservatif untuk membantu reuse koneksi
    • Jika sebelumnya mengandalkan Close untuk menghentikan unduhan besar lebih awal, reuse harus dinonaktifkan dengan Transport.DisableKeepAlives
  • Server HTTP/2 memahami prioritas klien RFC 9218 dan memproses stream prioritas tinggi lebih dulu
    • Server.DisableClientPriority = true dapat memulihkan perilaku round-robin sebelumnya
  • crypto/x509.SystemCertPool di Windows dan macOS mendukung SSL_CERT_FILE dan SSL_CERT_DIR
    • Jika variabel diatur, sertifikat root dibaca dari disk dan verifier Go dipakai alih-alih API platform
    • Bisa dinonaktifkan dengan GODEBUG=x509sslcertoverrideplatform=0
  • Implementasi HTTP/2 yang sebelumnya dibundel dalam file hasil generate h2_bundle.go sepanjang 12.226 baris kini diganti dengan paket nyata net/http/internal/http2
  • net/http menambahkan hook HTTP/3 yang dapat dipasang namun masih tahap pra-publikasi, dan sebagian test suite dijalankan di HTTP/3
    • Belum ada API publik yang dapat dipanggil, tetapi fondasinya untuk http.Transport berbasis QUIC di masa depan sudah disertakan

Toolchain

  • go test kini secara default menjalankan pemeriksaan vet stdversion untuk menemukan penggunaan simbol pustaka standar yang lebih baru daripada versi Go yang dideklarasikan di go.mod
  • go doc pkg@version dapat digunakan untuk melihat dokumentasi versi modul tertentu
  • go doc -ex menampilkan contoh yang bisa dieksekusi, dan jika nama contoh disebut langsung maka source-nya akan ditampilkan
  • go fix menambahkan analyzer modernisasi atomictypes, embedlit, slicesbackward, unsafefuncs
    • waitgroup berganti nama menjadi waitgroupgo dan fmtappendf dihapus
  • Pada modul Go 1.27 ke atas, go mod tidy menggabungkan blok require yang tersebar menjadi dua blok untuk dependensi langsung dan tidak langsung sambil mempertahankan komentar
  • go tool trace -http=:6060 akan bind hanya ke localhost bila hanya port yang diberikan; untuk akses eksternal, alamat harus disebutkan eksplisit
  • Perintah go menghapus dukungan untuk sistem kontrol versi Bazaar (bzr)
  • compile, link, asm, cgo, cover, pack mendukung response file (@file) bergaya GCC untuk menghindari batas panjang command line

Unicode dan batas keamanan

  • Data Unicode di pustaka standar diperbarui dari Unicode 15 ke Unicode 17
    • Karakter yang ditambahkan di Unicode 16 juga kini diklasifikasikan dengan benar sebagai simbol atau karakter yang dapat dicetak
  • Masalah yang memungkinkan keluar dari root dengan os.Root.ReadDir dan Readdir telah diperbaiki
  • Penggunaan //go:linkname yang tidak disetujui kini dibuat lebih sulit
    • Direktif linknamestd menandai linkname yang hanya boleh diimpor oleh pustaka standar
    • Linker juga memeriksa akses linkname ke simbol assembly, sehingga kode yang bergantung pada simbol internal tidak resmi perlu diuji lebih awal

1 komentar

 
GN⁺ 2 jam lalu
Komentar di Lobste.rs
  • Mungkin ini rilis terbaik sepanjang masa. SIMD, uuid, jsonv2 akhirnya masuk

    • Sepertinya harus mendukung UUID v5 juga agar bisa bermigrasi sepenuhnya
  • Agak melenceng dari topik, tetapi ini contoh bagus bagaimana bug muncul ketika memperlakukan semuanya sebagai string dan tidak mempertimbangkan kontrak serta keterkaitan antar-metode interface
    Equal mengabaikan huruf besar-kecil, tetapi Hash memakai nilai yang sudah diubah ke huruf kecil. Namun EqualFold dan ToLower tidak mendefinisikan relasi kesetaraan yang sama
    https://github.com/golang/go/issues/52204
    "\u017F" (ſ, s panjang) dan "s" sama menurut EqualFold, tetapi hasil ToLower masing-masing berbeda. Jadi jika memasukkan "s" lalu "ſ", hash-nya berbeda sehingga dimasukkan sebagai entri terpisah
    Yang lebih menarik, dokumentasinya memperingatkan tepat tentang kasus ini
    https://github.com/golang/go/…

  • Senang ada orang lain yang melanjutkan dari titik Anton berhenti

    • Sayangnya setidaknya sebagian, terutama bagian penggunaan JSON v2 secara default, tampaknya ditulis dengan LLM. Saya tidak suka gaya tulisannya, tetapi isinya tetap menarik
    • Sepertinya Anton bukan berhenti. Ia juga menulis untuk 1.26, jadi tampaknya tulisan kali ini dipublikasikan lebih dulu oleh orang lain
  • Saya suka Go, tetapi saya bertanya-tanya apakah sintaks Go cukup elegan untuk terus menambahkan fitur seperti ini di setiap rilis
    func (b Box[T]) Map[U any](f func(T) U) Box[U] {

    • Ini subjektif, tetapi saya tidak menganggapnya lebih buruk daripada bahasa lain yang mendukung fitur ini. Zig paling mirip, sementara Rust, TypeScript, dan C++20 umumnya menjadikan tipe sebagai kontainer definisi metode sehingga mengurangi biaya mengulang tipe receiver di banyak metode
      Sebaliknya, verbosity pada Go dan Zig enak karena tidak perlu menggulir ke tempat lain untuk mencari definisi receiver. Di titik pemanggilan, yang bisa dianggap lebih penting daripada bagian definisi, semuanya tampak hampir sama dan tidak perlu menyebutkan tipenya
  • Saya sudah cukup lama meninggalkan Go, dan jsonv2 membuat saya antusias. Namun jika ini menjadi default, saya bertanya-tanya apakah itu tidak melanggar janji kompatibilitas yang sudah lama dijaga Go

    • jsonv2 harus diimpor dari path terpisah, encoding/json/v2, jadi harus dipilih secara eksplisit. encoding/json yang lama memakai v2 secara internal, tetapi tetap menjamin perilaku sebelumnya, dan jsonv2 juga menyediakan flag untuk mereproduksi perilaku pengecualian v1, sehingga tidak melanggar janji kompatibilitas
    • Di proyek Go 1.26, saya memakai library jsontext dari v2 dan sangat puas