Ghi chú phát hành Go 1.26
Giới thiệu về Go 1.26
Bản phát hành Go mới nhất, phiên bản 1.26, ra đời vào tháng 2 năm 2026, sáu tháng sau Go 1.25. Phần lớn các thay đổi nằm ở phần triển khai toolchain, runtime và thư viện. Như thường lệ, bản phát hành này duy trì cam kết tương thích của Go 1. Chúng tôi kỳ vọng hầu hết các chương trình Go sẽ tiếp tục biên dịch và chạy như trước đây.
Thay đổi về ngôn ngữ
Hàm built-in new, dùng để tạo một biến mới, hiện cho phép
toán hạng của nó là một biểu thức, chỉ định giá trị ban đầu của
biến.
Tính năng này đặc biệt hữu ích khi làm việc với các gói serialization
như encoding/json hoặc protocol buffer sử dụng con trỏ để biểu diễn giá trị tùy chọn, vì nó cho phép
điền một trường tùy chọn trong một biểu thức đơn giản, ví dụ:
import "encoding/json"
type Person struct {
Name string `json:"name"`
Age *int `json:"age"` // age if known; nil otherwise
}
func personJSON(name string, born time.Time) ([]byte, error) {
return json.Marshal(Person{
Name: name,
Age: new(yearsSince(born)),
})
}
func yearsSince(t time.Time) int {
return int(time.Since(t).Hours() / (365.25 * 24)) // approximately
}
Hạn chế rằng một kiểu generic không được tham chiếu chính nó trong danh sách tham số kiểu
đã được dỡ bỏ.
Hiện có thể chỉ định các ràng buộc kiểu (type constraint) tham chiếu đến kiểu generic đang được
ràng buộc.
Ví dụ, một kiểu generic Adder có thể yêu cầu nó được khởi tạo với
một kiểu giống chính nó:
type Adder[A Adder[A]] interface {
Add(A) A
}
func algo[A Adder[A]](x, y A) A {
return x.Add(y)
}
Trước đây, tham chiếu tự đến Adder ở dòng đầu tiên không được cho phép.
Ngoài việc làm cho các ràng buộc kiểu mạnh hơn, thay đổi này cũng đơn giản hóa các quy tắc spec
cho tham số kiểu đôi chút.
Công cụ
Lệnh Go
Lệnh go fix truyền thống đã được đại tu hoàn toàn và hiện là nơi chứa
các modernizer của Go. Nó cung cấp một cách đáng tin cậy để cập nhật
code base Go lên các idiom và API thư viện lõi mới nhất. Bộ modernizer ban đầu bao gồm
hàng chục fixer để tận dụng các tính năng hiện đại của ngôn ngữ
và thư viện Go, cũng như một inliner ở cấp độ nguồn cho phép người dùng
tự động hóa các lần chuyển đổi API của riêng họ bằng cách sử dụng
chỉ thị //go:fix inline.
Các fixer này không nên thay đổi hành vi của chương trình, vì vậy nếu bạn gặp
bất kỳ vấn đề nào với một sửa chữa được thực hiện bởi go fix, vui lòng báo cáo.
Lệnh go fix được viết lại dựa trên chính framework phân tích
Go như go vet.
Điều này có nghĩa là các analyzer cung cấp chẩn đoán trong go vet
có thể được dùng để đề xuất và áp dụng các sửa chữa trong go fix.
Các fixer lịch sử của lệnh go fix, tất cả đều lỗi thời,
đã được loại bỏ.
Hai bài đăng blog Go sắp tới sẽ đi vào chi tiết hơn về modernizer, inliner,
và cách tận dụng tốt nhất go fix.
go mod init hiện mặc định phiên bản go thấp hơn trong các tệp go.mod mới.
Chạy go mod init
bằng toolchain phiên bản 1.N.X sẽ tạo tệp go.mod
chỉ định phiên bản Go go 1.(N-1).0. Các phiên bản pre-release của 1.N sẽ
tạo các tệp go.mod chỉ định go 1.(N-2).0. Ví dụ, các
release candidate Go 1.26 sẽ tạo các tệp go.mod với go 1.24.0, và Go 1.26
cùng các bản phát hành nhỏ của nó sẽ tạo các tệp go.mod với go 1.25.0. Điều này nhằm
khuyến khích tạo các module tương thích với các phiên bản Go hiện đang được hỗ trợ. Để kiểm soát thêm về phiên bản go trong các module mới,
go mod init có thể được tiếp theo bởi go get go@version.
cmd/doc và go tool doc đã bị xóa. go doc có thể được dùng như
một thay thế cho go tool doc: nó nhận cùng cờ và đối số và
có cùng hành vi.
Pprof
Giao diện web của công cụ pprof, được bật bằng cờ -http, hiện mặc định sử dụng chế độ xem flame graph.
Chế độ xem đồ thị trước đây vẫn có sẵn trong menu “View -> Graph”, hoặc qua /ui/graph.
Runtime
Bộ gom rác mới
Bộ gom rác Green Tea, trước đây có sẵn như một thử nghiệm trong Go 1.25, hiện được bật mặc định sau khi tiếp nhận phản hồi.
Thiết kế của bộ gom rác này cải thiện hiệu suất của việc marking và scanning các đối tượng nhỏ thông qua cải thiện locality và khả năng mở rộng CPU. Kết quả benchmark thay đổi, nhưng chúng tôi kỳ vọng giảm từ 10 đến 40% chi phí garbage collection trong các chương trình thực tế sử dụng nhiều bộ gom rác. Cải thiện thêm, khoảng 10% chi phí garbage collection, được kỳ vọng khi chạy trên các nền tảng CPU dựa trên amd64 mới hơn (Intel Ice Lake hoặc AMD Zen 4 trở lên), vì bộ gom rác hiện tận dụng các lệnh vector để scanning các đối tượng nhỏ khi có thể.
Bộ gom rác mới có thể bị tắt bằng cách đặt
GOEXPERIMENT=nogreenteagc tại thời điểm build.
Cài đặt opt-out này dự kiến sẽ bị loại bỏ trong Go 1.27.
Nếu bạn tắt bộ gom rác mới vì bất kỳ lý do nào liên quan đến
hiệu suất hoặc hành vi của nó, vui lòng gửi issue.
Lệnh gọi cgo nhanh hơn
Chi phí runtime cơ bản của các lệnh gọi cgo đã giảm khoảng 30%.
Ngẫu nhiên hóa địa chỉ cơ sở heap
Trên các nền tảng 64-bit, runtime hiện ngẫu nhiên hóa địa chỉ cơ sở heap
khi khởi động.
Đây là một cải tiến bảo mật giúp kẻ tấn công khó dự đoán địa chỉ bộ nhớ
và khai thác lỗ hổng khi sử dụng cgo hơn.
Tính năng này có thể bị tắt bằng cách đặt
GOEXPERIMENT=norandomizedheapbase64 tại thời điểm build.
Cài đặt opt-out này dự kiến sẽ bị loại bỏ trong một bản phát hành Go tương lai.
Profile rò rỉ goroutine thử nghiệm
Một kiểu profile mới báo cáo goroutine bị rò rỉ hiện có sẵn như một
thử nghiệm.
Kiểu profile mới, có tên goroutineleak trong gói
runtime/pprof, có thể được bật bằng cách đặt
GOEXPERIMENT=goroutineleakprofile tại thời điểm build.
Bật thử nghiệm cũng làm cho profile có sẵn như một
endpoint của net/http/pprof,
/debug/pprof/goroutineleak.
Một goroutine bị rò rỉ là goroutine bị chặn trên một nguyên thủy đồng thời
(channel, sync.Mutex, sync.Cond, v.v.) mà
không thể bị bỏ chặn.
Runtime phát hiện goroutine bị rò rỉ bằng bộ gom rác: nếu
goroutine G bị chặn trên nguyên thủy đồng thời P, và P không thể được truy cập từ
bất kỳ goroutine có thể chạy nào hoặc bất kỳ goroutine nào mà những goroutine đó có thể bỏ chặn, thì P
không thể bị bỏ chặn, vì vậy goroutine G không bao giờ có thể thức dậy.
Mặc dù không thể phát hiện tất cả các goroutine bị chặn vĩnh viễn trong mọi trường hợp,
phương pháp này phát hiện một lớp lớn các rò rỉ như vậy.
Ví dụ sau đây trình bày một rò rỉ goroutine trong thực tế có thể được tiết lộ bởi profile mới:
type result struct {
res workResult
err error
}
func processWorkItems(ws []workItem) ([]workResult, error) {
// Process work items in parallel, aggregating results in ch.
ch := make(chan result)
for _, w := range ws {
go func() {
res, err := processWorkItem(w)
ch <- result{res, err}
}()
}
// Collect the results from ch, or return an error if one is found.
var results []workResult
for range len(ws) {
r := <-ch
if r.err != nil {
// This early return may cause goroutine leaks.
return nil, r.err
}
results = append(results, r.res)
}
return results, nil
}
Vì ch không có buffer, nếu processWorkItems trả về sớm do
lỗi, tất cả các goroutine processWorkItem còn lại sẽ bị rò rỉ.
Ngay sau khi điều này xảy ra, ch sẽ trở nên không thể truy cập đối với tất cả các
goroutine khác không tham gia vào rò rỉ, cho phép runtime phát hiện
và báo cáo các goroutine bị rò rỉ.
Vì kỹ thuật này dựa trên khả năng truy cập, runtime có thể không xác định được các rò rỉ gây ra bởi việc chặn trên các nguyên thủy đồng thời có thể truy cập qua các biến toàn cục hoặc các biến cục bộ của các goroutine có thể chạy.
Đặc biệt cảm ơn Vlad Saioc tại Uber đã đóng góp công việc này. Lý thuyết nền tảng được trình bày chi tiết trong một bài đăng của Saioc et al.
Việc triển khai đã sẵn sàng cho môi trường sản xuất, và chỉ được coi là thử nghiệm để thu thập phản hồi về API, cụ thể là lựa chọn biến nó thành một profile mới. Tính năng cũng được thiết kế để không phát sinh bất kỳ chi phí runtime bổ sung nào trừ khi nó đang được sử dụng chủ động.
Chúng tôi khuyến khích người dùng thử nghiệm tính năng mới trong Go playground, trong các kiểm thử, trong tích hợp liên tục và trong môi trường sản xuất. Chúng tôi hoan nghênh phản hồi bổ sung trên issue đề xuất.
Chúng tôi mục tiêu bật goroutine leak profile theo mặc định trong Go 1.27.
Trình biên dịch
Trình biên dịch hiện có thể phân bổ bộ nhớ hỗ trợ cho slice trên stack trong nhiều
tình huống hơn, giúp cải thiện hiệu suất. Nếu thay đổi này gây ra sự cố, công cụ
bisect có thể được dùng để
tìm phân bổ gây ra sự cố bằng cờ -compile=variablemake. Tất cả
các phân bổ stack mới như vậy cũng có thể được tắt bằng cách dùng
-gcflags=all=-d=variablemakehash=n.
Nếu bạn gặp vấn đề với tối ưu hóa này, vui lòng gửi issue.
Linker
Trên Windows dựa trên ARM 64-bit (cổng windows/arm64), linker hiện hỗ trợ chế độ
liên kết nội bộ (internal linking mode) của các chương trình cgo, có thể được yêu cầu bằng cờ
-ldflags=-linkmode=internal.
Có một số thay đổi nhỏ đối với các tệp thực thi. Những thay đổi này không ảnh hưởng đến việc chạy các chương trình Go. Chúng có thể ảnh hưởng đến các chương trình phân tích binary Go, và có thể ảnh hưởng đến những người dùng chế độ liên kết ngoài với script linker tùy chỉnh.
- Cấu trúc
moduledatahiện nằm trong phần riêng của nó, có tên.go.module. - Trường
cutabcủamoduledata, là một slice, hiện có độ dài đúng; trước đây độ dài bị gấp bốn lần. pcHeaderđược tìm thấy ở đầu phần.gopclntabkhông còn ghi lại điểm bắt đầu của phần text. Trường đó hiện luôn là không.- Thay đổi
pcHeaderđó được thực hiện để phần.gopclntabkhông còn chứa bất kỳ relocation nào. Trên các nền tảng hỗ trợ relro, phần đã chuyển từ segment relro sang segment rodata. - Các ký hiệu funcdata và findfunctab đã chuyển từ phần
.rodatasang phần.gopclntab. - Phần
.gosymtabđã bị xóa. Trước đây nó luôn có mặt nhưng rỗng. - Khi sử dụng liên kết nội bộ, các phần ELF hiện xuất hiện trong danh sách section header được sắp xếp theo địa chỉ. Thứ tự trước đây khá khó đoán.
Các tham chiếu đến tên phần ở đây dùng tên ELF như được thấy trên Linux và các hệ thống khác. Tên Mach-O như được thấy trên Darwin bắt đầu bằng dấu gạch dưới kép và không chứa bất kỳ dấu chấm nào.
Bootstrap
Như đã đề cập trong ghi chú phát hành Go 1.24, Go 1.26 hiện yêu cầu Go 1.24.6 trở lên để bootstrap. Chúng tôi kỳ vọng rằng Go 1.28 sẽ yêu cầu một bản phát hành nhỏ của Go 1.26 trở lên để bootstrap.
Thư viện chuẩn
Gói crypto/hpke mới
Gói mới crypto/hpke triển khai Hybrid Public Key Encryption
(HPKE) theo đặc tả trong RFC 9180, bao gồm hỗ trợ cho các
hybrid KEM hậu lượng tử (post-quantum hybrid KEM).
Gói simd/archsimd thử nghiệm mới
Go 1.26 giới thiệu gói thử nghiệm mới simd/archsimd,
có thể được bật bằng cách đặt biến môi trường
GOEXPERIMENT=simd tại thời điểm build.
Gói này cung cấp quyền truy cập vào các thao tác SIMD đặc thù kiến trúc.
Hiện có sẵn trên kiến trúc amd64 và hỗ trợ
các kiểu vector 128-bit, 256-bit và 512-bit, chẳng hạn như
Int8x16 và
Float64x8, với các thao tác như
Int8x16.Add.
API chưa được coi là ổn định.
Chúng tôi có kế hoạch hỗ trợ các kiến trúc khác trong các phiên bản tương lai, nhưng API có chủ ý đặc thù kiến trúc và do đó không di động. Ngoài ra, chúng tôi có kế hoạch phát triển một gói SIMD di động cấp cao trong tương lai.
Xem tài liệu gói và issue đề xuất để biết thêm chi tiết.
Gói runtime/secret thử nghiệm mới
Gói mới runtime/secret có sẵn như một thử nghiệm,
có thể được bật bằng cách đặt biến môi trường
GOEXPERIMENT=runtimesecret tại thời điểm build.
Nó cung cấp phương tiện để xóa an toàn các biến tạm thời được dùng trong
code thao tác thông tin bí mật (thường là mã hóa), chẳng hạn như
thanh ghi, stack, phân bổ heap mới.
Gói này nhằm giúp dễ dàng đảm bảo bảo mật tiếp theo
(forward secrecy).
Hiện hỗ trợ kiến trúc amd64 và arm64 trên Linux.
Các thay đổi nhỏ trong thư viện
bytes
Phương thức mới Buffer.Peek trả về n byte tiếp theo từ buffer mà không
tiến buffer.
crypto
Các interface mới Encapsulator và Decapsulator cho phép chấp nhận
khóa đóng gói (encapsulation) hoặc giải đóng gói (decapsulation) KEM trừu tượng.
crypto/dsa
Tham số random trong GenerateKey hiện bị bỏ qua.
Thay vào đó, nó hiện luôn dùng nguồn byte ngẫu nhiên bảo mật về mặt mã hóa.
Để kiểm thử xác định, dùng hàm mới testing/cryptotest.SetGlobalRandom.
Cài đặt GODEBUG mới cryptocustomrand=1 tạm thời khôi phục hành vi cũ.
crypto/ecdh
Tham số random trong Curve.GenerateKey hiện bị bỏ qua.
Thay vào đó, nó hiện luôn dùng nguồn byte ngẫu nhiên bảo mật về mặt mã hóa.
Để kiểm thử xác định, dùng hàm mới testing/cryptotest.SetGlobalRandom.
Cài đặt GODEBUG mới cryptocustomrand=1 tạm thời khôi phục hành vi cũ.
Interface mới KeyExchanger, được triển khai bởi PrivateKey, giúp có thể
chấp nhận các khóa riêng ECDH trừu tượng, ví dụ: các khóa được triển khai trong phần cứng.
crypto/ecdsa
Các trường big.Int của PublicKey và PrivateKey hiện không còn được khuyến nghị (deprecated).
Tham số random trong GenerateKey, SignASN1, Sign, và PrivateKey.Sign hiện bị bỏ qua.
Thay vào đó, chúng hiện luôn dùng nguồn byte ngẫu nhiên bảo mật về mặt mã hóa.
Để kiểm thử xác định, dùng hàm mới testing/cryptotest.SetGlobalRandom.
Cài đặt GODEBUG mới cryptocustomrand=1 tạm thời khôi phục hành vi cũ.
crypto/ed25519
Nếu tham số random trong GenerateKey là nil, GenerateKey hiện luôn dùng
nguồn byte ngẫu nhiên bảo mật về mặt mã hóa, thay vì crypto/rand.Reader
(có thể đã bị ghi đè). Cài đặt GODEBUG mới cryptocustomrand=1
tạm thời khôi phục hành vi cũ.
crypto/fips140
Module Mã hóa Go FIPS 140-3 v1.26.0 bao gồm các thay đổi được thực hiện đối với các gói crypto/internal/fips140/... đến bản phát hành này, và hiện có thể được chọn bằng GOFIPS140.
Các hàm mới WithoutEnforcement và Enforced hiện cho phép chạy
trong chế độ GODEBUG=fips140=only đồng thời vô hiệu hóa có chọn lọc các kiểm tra FIPS 140-3 nghiêm ngặt.
Version trả về phiên bản Module Mã hóa Go FIPS 140-3 đã giải quyết khi build với module đông lạnh bằng GOFIPS140.
crypto/mlkem
Các phương thức mới DecapsulationKey768.Encapsulator và
DecapsulationKey1024.Encapsulator triển khai interface
crypto.Decapsulator mới.
Các thao tác đóng gói và giải đóng gói hiện nhanh hơn khoảng 18%.
crypto/mlkem/mlkemtest
Gói mới crypto/mlkem/mlkemtest cung cấp các hàm Encapsulate768 và
Encapsulate1024 triển khai đóng gói ML-KEM không ngẫu nhiên (derandomized),
để dùng với các kiểm thử đáp án đã biết (known-answer test).
crypto/rand
Tham số random trong Prime hiện bị bỏ qua.
Thay vào đó, nó hiện luôn dùng nguồn byte ngẫu nhiên bảo mật về mặt mã hóa.
Để kiểm thử xác định, dùng hàm mới testing/cryptotest.SetGlobalRandom.
Cài đặt GODEBUG mới cryptocustomrand=1 tạm thời khôi phục hành vi cũ.
crypto/rsa
Hàm mới EncryptOAEPWithOptions cho phép chỉ định các hàm hash khác nhau
cho padding OAEP và tạo mặt nạ MGF1.
Tham số random trong GenerateKey, GenerateMultiPrimeKey, và EncryptPKCS1v15 hiện bị bỏ qua.
Thay vào đó, chúng hiện luôn dùng nguồn byte ngẫu nhiên bảo mật về mặt mã hóa.
Để kiểm thử xác định, dùng hàm mới testing/cryptotest.SetGlobalRandom.
Cài đặt GODEBUG mới cryptocustomrand=1 tạm thời khôi phục hành vi cũ.
Nếu các trường PrivateKey bị sửa đổi sau khi gọi PrivateKey.Precompute,
PrivateKey.Validate hiện sẽ thất bại.
PrivateKey.D hiện được kiểm tra tính nhất quán với các giá trị được tính trước, ngay cả khi
nó không được sử dụng.
Padding mã hóa PKCS #1 v1.5 không an toàn (được triển khai bởi EncryptPKCS1v15,
DecryptPKCS1v15, và DecryptPKCS1v15SessionKey) hiện không còn được khuyến nghị (deprecated).
crypto/sha3
Giá trị không (zero value) của SHA3 hiện là một instance SHA3-256 có thể dùng được, và giá trị không của SHAKE hiện là một instance SHAKE256 có thể dùng được.
crypto/subtle
Hàm WithDataIndependentTiming
không còn khóa goroutine gọi vào luồng OS trong khi thực thi
hàm được truyền vào. Ngoài ra, bất kỳ goroutine nào được sinh ra trong quá trình
thực thi hàm được truyền vào và các goroutine con của chúng hiện kế thừa các thuộc tính của
WithDataIndependentTiming trong suốt vòng đời của chúng. Thay đổi này cũng ảnh hưởng đến cgo theo
các cách sau:
- Bất kỳ code C nào được gọi qua cgo từ bên trong hàm được truyền vào
WithDataIndependentTiming, hoặc từ một goroutine được sinh ra bởi hàm được truyền vàoWithDataIndependentTimingvà các goroutine con của nó, cũng sẽ có data independent timing được bật trong suốt thời gian gọi. Nếu code C tắt data independent timing, nó sẽ được bật lại khi quay về Go. - Nếu code C được gọi qua cgo, từ hàm được truyền vào
WithDataIndependentTiminghoặc nơi khác, bật hoặc tắt data independent timing thì việc gọi vào Go sẽ giữ nguyên trạng thái đó trong suốt thời gian gọi.
crypto/tls
Các trao đổi khóa hậu lượng tử hybrid SecP256r1MLKEM768 và SecP384r1MLKEM1024
hiện được bật mặc định. Chúng có thể bị tắt bằng cách đặt
Config.CurvePreferences hoặc với cài đặt GODEBUG tlssecpmlkem=0.
Trường mới ClientHelloInfo.HelloRetryRequest cho biết liệu ClientHello
có được gửi để phản hồi tin nhắn HelloRetryRequest không. Trường mới
ConnectionState.HelloRetryRequest cho biết liệu server
đã gửi HelloRetryRequest, hay client đã nhận HelloRetryRequest,
tùy thuộc vào vai trò kết nối.
Kiểu QUICConn được dùng bởi các triển khai QUIC bao gồm một sự kiện mới
để báo cáo lỗi TLS handshake.
Nếu Certificate.PrivateKey triển khai crypto.MessageSigner, phương thức SignMessage của nó
được dùng thay vì Sign trong TLS 1.2 và mới hơn.
Các cài đặt GODEBUG sau được giới thiệu trong Go 1.22 và Go 1.23 sẽ bị loại bỏ trong bản phát hành Go lớn tiếp theo. Bắt đầu từ Go 1.27, hành vi mới sẽ áp dụng bất kể cài đặt GODEBUG hay phiên bản ngôn ngữ go.mod.
tlsunsafeekm:ConnectionState.ExportKeyingMaterialsẽ yêu cầu TLS 1.3 hoặc Extended Master Secret.tlsrsakex: các trao đổi khóa RSA-only cũ không có ECDH sẽ không được bật mặc định.tls10server: phiên bản TLS tối thiểu mặc định cho cả client và server sẽ là TLS 1.2.tls3des: các cipher suite mặc định sẽ không bao gồm 3DES.x509keypairleaf:X509KeyPairvàLoadX509KeyPairsẽ luôn điền trườngCertificate.Leaf.
crypto/x509
Các kiểu ExtKeyUsage và KeyUsage hiện có các phương thức String trả về
các tên OID tương ứng như được định nghĩa trong RFC 5280 và các registry khác.
Kiểu ExtKeyUsage hiện có một phương thức OID trả về OID tương ứng cho EKU.
Hàm mới OIDFromASN1OID cho phép chuyển đổi một encoding/asn1.ObjectIdentifier thành
một OID.
debug/elf
Các hằng số R_LARCH_* bổ sung từ LoongArch ELF psABI v20250521
(phiên bản toàn cục v2.40) được định nghĩa để dùng với các hệ thống LoongArch.
errors
Hàm mới AsType là phiên bản generic của As. Nó an toàn về kiểu, nhanh hơn,
và trong hầu hết các trường hợp, dễ sử dụng hơn.
fmt
Đối với các chuỗi không được định dạng, fmt.Errorf("x") hiện phân bổ ít hơn và nhìn chung khớp với
số phân bổ của errors.New("x").
go/ast
Hàm mới ParseDirective phân tích cú pháp comment
chỉ thị (directive comment), là các comment như //go:generate.
Các công cụ mã nguồn có thể hỗ trợ các comment chỉ thị của riêng họ và API mới này
sẽ giúp họ triển khai cú pháp theo quy ước.
Trường mới BasicLit.ValueEnd ghi lại vị trí kết thúc chính xác của
một literal để phương thức BasicLit.End hiện luôn có thể trả về
câu trả lời đúng. (Trước đây nó được tính bằng heuristic không chính xác
đối với các raw string literal đa dòng trong các tệp nguồn Windows,
do việc loại bỏ ký tự xuống dòng.)
Các chương trình cập nhật trường ValuePos của BasicLit được tạo bởi
parser có thể cần cập nhật hoặc xóa trường ValueEnd để
tránh sự khác biệt nhỏ trong output được định dạng.
go/token
Phương thức tiện ích mới File.End trả về vị trí kết thúc của tệp.
go/types
Cài đặt GODEBUG gotypesalias được giới thiệu trong Go 1.22
sẽ bị loại bỏ trong bản phát hành Go lớn tiếp theo.
Bắt đầu từ Go 1.27, gói go/types sẽ luôn tạo ra
kiểu Alias để biểu diễn type alias
bất kể cài đặt GODEBUG hay phiên bản ngôn ngữ go.mod.
image/jpeg
Bộ mã hóa và giải mã JPEG đã được thay thế bằng các triển khai mới, nhanh hơn và chính xác hơn. Code mong đợi output bit-cho-bit cụ thể từ bộ mã hóa hoặc giải mã có thể cần được cập nhật.
io
ReadAll hiện phân bổ ít bộ nhớ trung gian hơn và trả về một
slice cuối có kích thước tối thiểu. Nó thường nhanh hơn khoảng hai lần trong khi
thường phân bổ tổng cộng khoảng một nửa bộ nhớ, với lợi ích nhiều hơn cho các đầu vào lớn hơn.
log/slog
Hàm NewMultiHandler tạo một
MultiHandler gọi tất cả các Handler đã cho.
Phương thức Enabled của nó báo cáo liệu có bất kỳ phương thức Enabled nào của các handler
trả về true không.
Các phương thức Handle, WithAttrs và WithGroup của nó gọi phương thức tương ứng
trên mỗi handler được bật.
net
Các phương thức mới của Dialer
DialIP,
DialTCP,
DialUDP, và
DialUnix
cho phép dial các kiểu mạng cụ thể với giá trị context.
net/http
Trường mới
HTTP2Config.StrictMaxConcurrentRequests
kiểm soát liệu có nên mở một kết nối mới
khi kết nối HTTP/2 hiện có đã vượt quá giới hạn stream không.
Phương thức mới Transport.NewClientConn trả về một kết nối client
đến server HTTP.
Hầu hết người dùng nên tiếp tục dùng Transport.RoundTrip để thực hiện yêu cầu,
vốn quản lý một nhóm kết nối.
NewClientConn hữu ích cho người dùng cần triển khai quản lý kết nối của riêng họ.
Client hiện dùng và đặt cookie có phạm vi đến các URL với phần host khớp với
Request.Host khi có sẵn.
Trước đây, host của địa chỉ kết nối luôn được dùng.
Các chuyển hướng dấu gạch chéo theo sau (trailing slash redirect) của ServeMux hiện sử dụng HTTP status 307
(Temporary Redirect) thay vì 301 (Moved Permanently).
net/http/httptest
HTTP client được trả về bởi Server.Client sẽ hiện chuyển hướng các yêu cầu cho
example.com và bất kỳ subdomain nào đến server đang được kiểm thử.
net/http/httputil
Trường cấu hình ReverseProxy.Director không còn được khuyến nghị (deprecated)
thay cho ReverseProxy.Rewrite.
Một client độc hại có thể xóa các header được thêm bởi hàm Director
bằng cách chỉ định các header đó là hop-by-hop. Vì không có cách nào để giải quyết
vấn đề này trong phạm vi API Director, chúng tôi đã thêm một hook
Rewrite mới trong Go 1.20. Các hook Rewrite được cung cấp cả
yêu cầu đến chưa được sửa đổi mà proxy nhận được và yêu cầu đi ra
sẽ được proxy gửi đi.
Vì hook Director về cơ bản là không an toàn, chúng tôi hiện đang không còn khuyến nghị (deprecate) nó.
net/netip
Phương thức mới Prefix.Compare so sánh hai prefix.
net/url
Parse hiện từ chối các URL không đúng định dạng chứa dấu hai chấm trong subcomponent host,
chẳng hạn như http://::1/ hoặc http://localhost:80:80/.
Các URL chứa địa chỉ IPv6 có dấu ngoặc, chẳng hạn như http://[::1]/ vẫn được chấp nhận.
Cài đặt GODEBUG mới urlstrictcolons=0 khôi phục hành vi cũ.
os
Phương thức mới Process.WithHandle cung cấp
quyền truy cập vào một handle tiến trình nội bộ trên các nền tảng được hỗ trợ (pidfd trên Linux 5.4
trở lên, Handle trên Windows).
Trên Windows, tham số flag của OpenFile hiện có thể chứa bất kỳ tổ hợp nào của
các cờ tệp đặc thù Windows, chẳng hạn như FILE_FLAG_OVERLAPPED và
FILE_FLAG_SEQUENTIAL_SCAN, để kiểm soát hành vi caching tệp hoặc thiết bị,
chế độ truy cập và các cờ mục đích đặc biệt khác.
os/signal
NotifyContext hiện hủy context được trả về bằng context.CancelCauseFunc
và một lỗi cho biết tín hiệu nào đã được nhận.
reflect
Các phương thức mới Type.Fields,
Type.Methods,
Type.Ins
và Type.Outs
trả về các iterator cho các trường của kiểu (đối với kiểu struct), phương thức,
tham số đầu vào và đầu ra (đối với kiểu hàm).
Tương tự, các phương thức mới Value.Fields
và Value.Methods trả về các iterator qua
các trường hoặc phương thức của một giá trị.
Mỗi lần lặp trả về thông tin kiểu (StructField hoặc
Method) của một trường hoặc phương thức,
cùng với Value của trường hoặc phương thức đó.
runtime/metrics
Một số metric scheduler mới đã được thêm vào, bao gồm số lượng
goroutine ở các trạng thái khác nhau (đang chờ, có thể chạy, v.v.) dưới
prefix /sched/goroutines, số luồng OS mà runtime
biết đến với /sched/threads:threads, và tổng số
goroutine được tạo bởi chương trình với
/sched/goroutines-created:goroutines.
testing
Các phương thức mới T.ArtifactDir, B.ArtifactDir, và F.ArtifactDir
trả về một thư mục để ghi các tệp output kiểm thử (artifact).
Khi cờ -artifacts được cung cấp cho go test,
thư mục này sẽ nằm dưới thư mục output
(được chỉ định bằng -outputdir, hoặc thư mục hiện tại theo mặc định).
Ngược lại, artifact được lưu trữ trong một thư mục tạm thời
sẽ bị xóa sau khi kiểm thử hoàn thành.
Lần gọi đầu tiên đến ArtifactDir khi -artifacts được cung cấp
ghi vị trí của thư mục vào log kiểm thử.
Ví dụ, trong một kiểm thử có tên TestArtifacts,
t.ArtifactDir() phát ra:
=== ARTIFACTS TestArtifacts /path/to/artifact/dir
Phương thức B.Loop không còn ngăn cản việc inline trong
thân vòng lặp, điều này có thể dẫn đến phân bổ không mong đợi và benchmark chậm hơn.
Với bản sửa lỗi này, chúng tôi kỳ vọng tất cả các benchmark có thể được chuyển đổi từ phong cách
B.N cũ sang phong cách B.Loop mới mà không có tác dụng phụ.
Trong thân vòng lặp for b.Loop() { ... }, các tham số lệnh gọi hàm, kết quả,
và các biến được gán vẫn được giữ sống, ngăn trình biên dịch
tối ưu hóa bỏ toàn bộ phần của benchmark.
testing/cryptotest
Hàm mới SetGlobalRandom cấu hình một nguồn ngẫu nhiên mã hóa xác định toàn cục
trong suốt thời gian kiểm thử. Nó ảnh hưởng đến
crypto/rand, và tất cả các nguồn ngẫu nhiên mã hóa ngầm trong các gói
crypto/....
time
Cài đặt GODEBUG asynctimerchan được giới thiệu trong Go 1.23
sẽ bị loại bỏ trong bản phát hành Go lớn tiếp theo.
Bắt đầu từ Go 1.27, gói time sẽ luôn dùng các channel
không có buffer (đồng bộ) cho timer bất kể cài đặt GODEBUG hay phiên bản ngôn ngữ go.mod.
Nền tảng
Darwin
Go 1.26 là bản phát hành cuối cùng chạy được trên macOS 12 Monterey. Go 1.27 sẽ yêu cầu macOS 13 Ventura trở lên.
FreeBSD
Cổng freebsd/riscv64 (GOOS=freebsd GOARCH=riscv64) đã được đánh dấu là bị hỏng.
Xem issue 76475 để biết chi tiết.
Windows
Như đã thông báo trong ghi chú phát hành Go 1.25, cổng 32-bit windows/arm
đã bị hỏng (GOOS=windows
GOARCH=arm) đã bị loại bỏ.
PowerPC
Go 1.26 là bản phát hành cuối cùng hỗ trợ ELFv1 ABI trên cổng PowerPC 64-bit big-endian
trên Linux (GOOS=linux GOARCH=ppc64).
Nó sẽ chuyển sang ELFv2 ABI trong Go 1.27.
Vì cổng hiện không hỗ trợ liên kết với các đối tượng ELF khác,
chúng tôi kỳ vọng thay đổi này sẽ trong suốt đối với người dùng.
RISC-V
Cổng linux/riscv64 hiện hỗ trợ trình phát hiện race.
S390X
Cổng s390x hiện hỗ trợ truyền đối số và kết quả hàm bằng thanh ghi.
WebAssembly
Trình biên dịch hiện vô điều kiện sử dụng các lệnh mở rộng dấu (sign extension)
và chuyển đổi dấu phẩy động sang số nguyên không bẫy lỗi (non-trapping floating-point to integer conversion).
Các tính năng này đã được chuẩn hóa từ ít nhất Wasm 2.0.
Các cài đặt GOWASM tương ứng, signext và satconv, hiện bị bỏ qua.
Đối với các ứng dụng WebAssembly, runtime hiện quản lý các khối bộ nhớ heap theo các gia số nhỏ hơn nhiều, dẫn đến giảm đáng kể mức sử dụng bộ nhớ cho các ứng dụng có heap nhỏ hơn khoảng 16 MiB.