Ghi chú phát hành Go 1.19
Giới thiệu về Go 1.19
Bản phát hành Go mới nhất, phiên bản 1.19, ra đời năm tháng sau Go 1.18. 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ữ
Chỉ có một thay đổi nhỏ về ngôn ngữ, một sửa chữa rất nhỏ đối với phạm vi của type parameter trong khai báo phương thức. Các chương trình hiện tại không bị ảnh hưởng.
Mô hình bộ nhớ
Mô hình bộ nhớ Go đã được
xem xét lại để đồng bộ Go với
mô hình bộ nhớ được dùng bởi C, C++, Java, JavaScript, Rust và Swift.
Go chỉ cung cấp các atomic tuần tự nhất quán (sequentially consistent), không có bất kỳ dạng nới lỏng nào như trong các ngôn ngữ khác.
Cùng với việc cập nhật mô hình bộ nhớ,
Go 1.19 giới thiệu các kiểu mới trong gói sync/atomic
giúp sử dụng các giá trị atomic dễ dàng hơn, chẳng hạn như
atomic.Int64
và
atomic.Pointer[T].
Nền tảng
LoongArch 64-bit
Go 1.19 thêm hỗ trợ cho kiến trúc 64-bit Loongson
LoongArch
trên Linux (GOOS=linux, GOARCH=loong64).
ABI được triển khai là LP64D. Phiên bản kernel tối thiểu được hỗ trợ là 5.19.
Lưu ý rằng hầu hết các bản phân phối Linux thương mại hiện có cho LoongArch đi kèm với kernel cũ hơn, với ABI lệnh gọi hệ thống không tương thích trong lịch sử. Các binary đã biên dịch sẽ không chạy trên các hệ thống này, ngay cả khi được liên kết tĩnh. Người dùng trên các hệ thống không được hỗ trợ như vậy chỉ có thể dùng gói Go được cung cấp bởi bản phân phối.
RISC-V
Cổng riscv64 hiện hỗ trợ truyền đối số hàm
và kết quả bằng thanh ghi. Benchmark cho thấy cải thiện hiệu suất điển hình
từ 10% trở lên trên riscv64.
Công cụ
Nhận xét tài liệu (Doc Comments)
Go 1.19 thêm hỗ trợ cho link, danh sách và tiêu đề rõ ràng hơn trong comment tài liệu.
Là một phần của thay đổi này, gofmt
hiện định dạng lại comment tài liệu để làm rõ hơn ý nghĩa được render.
Xem “Go Doc Comments”
để biết chi tiết cú pháp và mô tả các lỗi phổ biến hiện được gofmt làm nổi bật.
Cũng là một phần của thay đổi này, gói mới go/doc/comment
cung cấp khả năng phân tích và định dạng lại comment tài liệu
cũng như hỗ trợ render chúng thành HTML, Markdown và text.
Ràng buộc build unix mới
Ràng buộc build unix hiện được nhận diện
trong các dòng //go:build. Ràng buộc được thỏa mãn
nếu hệ điều hành đích, còn gọi là GOOS, là
một hệ thống Unix hoặc giống Unix. Với bản phát hành 1.19, nó được thỏa mãn
nếu GOOS là một trong
aix, android, darwin,
dragonfly, freebsd, hurd,
illumos, ios, linux,
netbsd, openbsd, hoặc solaris.
Trong các bản phát hành tương lai, ràng buộc unix có thể khớp
với các hệ điều hành được hỗ trợ mới.
Lệnh Go
Cờ -trimpath, nếu được đặt, hiện được đưa vào cài đặt build
được đóng dấu vào các binary Go bởi go build, và có thể
được kiểm tra bằng cách dùng
go version -m
hoặc debug.ReadBuildInfo.
go generate hiện đặt biến môi trường GOROOT
một cách rõ ràng trong môi trường của generator, để
các generator có thể xác định GOROOT đúng ngay cả khi được build
với -trimpath.
go test và go generate hiện đặt
GOROOT/bin ở đầu PATH được dùng cho
tiến trình con, để các kiểm thử và generator thực thi lệnh go
sẽ phân giải nó đến cùng GOROOT.
go env hiện trích dẫn các mục chứa dấu cách trong
các biến CGO_CFLAGS, CGO_CPPFLAGS, CGO_CXXFLAGS, CGO_FFLAGS, CGO_LDFLAGS,
và GOGCCFLAGS mà nó báo cáo.
go list -json hiện chấp nhận một
danh sách các trường JSON được phân tách bằng dấu phẩy để điền vào. Nếu có danh sách,
output JSON sẽ chỉ bao gồm các trường đó, và
go list có thể tránh tính toán các trường không
được bao gồm. Trong một số trường hợp, điều này có thể ngăn chặn các lỗi mà
nếu không sẽ được báo cáo.
Lệnh go hiện cache thông tin cần thiết để tải một số module,
điều này sẽ giúp tăng tốc một số lần gọi go list.
Vet
Trình kiểm tra vet “errorsas” hiện báo cáo khi
errors.As được gọi
với đối số thứ hai kiểu *error,
một lỗi phổ biến.
Runtime
Runtime hiện bao gồm hỗ trợ cho giới hạn bộ nhớ mềm (soft memory limit). Giới hạn bộ nhớ này
bao gồm heap Go và tất cả bộ nhớ khác được runtime quản lý, và
loại trừ các nguồn bộ nhớ bên ngoài như mapping của chính binary,
bộ nhớ được quản lý bằng ngôn ngữ khác và bộ nhớ được hệ điều hành giữ
thay mặt chương trình Go. Giới hạn này có thể được quản lý qua
runtime/debug.SetMemoryLimit
hoặc biến môi trường tương đương
GOMEMLIMIT.
Giới hạn hoạt động kết hợp với
runtime/debug.SetGCPercent
/ GOGC,
và sẽ được tuân theo ngay cả khi GOGC=off, cho phép các chương trình Go
luôn sử dụng tối đa giới hạn bộ nhớ của chúng, cải thiện hiệu quả tài nguyên
trong một số trường hợp. Xem hướng dẫn GC để có
hướng dẫn chi tiết giải thích giới hạn bộ nhớ mềm, cũng như
nhiều trường hợp sử dụng và kịch bản phổ biến. Lưu ý rằng các giới hạn bộ nhớ nhỏ,
khoảng vài chục megabyte trở xuống, ít có khả năng được tuân theo
do các yếu tố độ trễ bên ngoài, chẳng hạn như lên lịch OS. Xem
issue 52433 để biết thêm chi tiết. Các
giới hạn bộ nhớ lớn hơn, khoảng hàng trăm megabyte trở lên, ổn định và
sẵn sàng cho môi trường sản xuất.
Để hạn chế tác động của GC thrashing khi kích thước heap sống của chương trình
tiến gần đến giới hạn bộ nhớ mềm, Go runtime cũng cố gắng giới hạn
tổng mức sử dụng CPU của GC ở mức 50%, không tính thời gian idle, chọn dùng nhiều bộ nhớ hơn
để ngăn chặn ứng dụng bị chậm lại. Trong thực tế, chúng tôi kỳ vọng giới hạn này
chỉ đóng vai trò trong các trường hợp ngoại lệ, và
runtime metric mới
/gc/limiter/last-enabled:gc-cycle báo cáo khi điều này lần cuối
xảy ra.
Runtime hiện lên lịch ít goroutine worker GC hơn trên các luồng hệ điều hành ở trạng thái idle khi ứng dụng đủ idle để buộc một chu kỳ GC định kỳ.
Runtime hiện sẽ phân bổ stack goroutine ban đầu dựa trên mức sử dụng stack trung bình lịch sử của goroutine. Điều này tránh một số tăng trưởng stack sớm và sao chép cần thiết trong trường hợp trung bình, đổi lại tối đa 2x không gian lãng phí trên các goroutine sử dụng dưới mức trung bình.
Trên các hệ điều hành Unix, các chương trình Go import gói
os hiện tự động tăng giới hạn file mở
(RLIMIT_NOFILE) lên giá trị tối đa cho phép;
tức là chúng thay đổi giới hạn mềm để khớp với giới hạn cứng.
Điều này sửa các giới hạn thấp giả tạo được đặt trên một số hệ thống để tương thích với các chương trình C rất cũ
sử dụng lệnh gọi hệ thống select.
Các chương trình Go không được hưởng lợi từ giới hạn đó, và thậm chí các chương trình đơn giản như gofmt
thường hết file descriptor trên các hệ thống như vậy khi xử lý nhiều tệp song song.
Một tác động của thay đổi này là các chương trình Go lần lượt thực thi các chương trình C rất cũ trong tiến trình con
có thể chạy các chương trình đó với giới hạn quá cao.
Điều này có thể được sửa bằng cách đặt giới hạn cứng trước khi gọi chương trình Go.
Các lỗi fatal không thể khôi phục (như ghi map đồng thời, hoặc unlock mutex
chưa bị lock) hiện in traceback đơn giản hơn, loại trừ metadata runtime
(tương đương với fatal panic) trừ khi GOTRACEBACK=system hoặc
crash. Traceback lỗi fatal nội bộ runtime luôn bao gồm
đầy đủ metadata bất kể giá trị của GOTRACEBACK.
Hỗ trợ cho các lệnh gọi hàm do debugger inject đã được thêm vào trên ARM64, cho phép người dùng gọi các hàm từ binary của họ trong một phiên gỡ lỗi tương tác khi sử dụng debugger được cập nhật để tận dụng chức năng này.
Hỗ trợ address sanitizer được thêm vào trong Go 1.18 hiện xử lý đối số hàm và biến toàn cục chính xác hơn.
Trình biên dịch
Trình biên dịch hiện sử dụng
bảng nhảy (jump table) để triển khai các câu lệnh switch số nguyên và chuỗi lớn.
Cải thiện hiệu suất cho câu lệnh switch thay đổi nhưng có thể
nhanh hơn khoảng 20%.
(Chỉ GOARCH=amd64 và GOARCH=arm64)
Trình biên dịch Go hiện yêu cầu cờ -p=importpath để
build một object file có thể liên kết. Điều này đã được cung cấp bởi
lệnh go và Bazel. Bất kỳ hệ thống build nào khác
gọi trình biên dịch Go trực tiếp sẽ cần đảm bảo chúng
truyền cờ này.
Trình biên dịch Go không còn chấp nhận cờ -importmap.
Các hệ thống build gọi trực tiếp trình biên dịch Go phải dùng
cờ -importcfg thay thế.
Assembler
Giống như trình biên dịch, assembler hiện yêu cầu
cờ -p=importpath để build một object file có thể liên kết.
Điều này đã được cung cấp bởi lệnh go. Bất kỳ hệ thống build nào khác
gọi trực tiếp assembler Go sẽ cần đảm bảo chúng
truyền cờ này.
Linker
Trên các nền tảng ELF, linker hiện phát ra các phần DWARF nén theo
định dạng gABI tiêu chuẩn (SHF_COMPRESSED), thay vì
định dạng kế thừa .zdebug.
Thư viện chuẩn
Các kiểu atomic mới
Gói sync/atomic định nghĩa các kiểu atomic mới
Bool,
Int32,
Int64,
Uint32,
Uint64,
Uintptr, và
Pointer.
Các kiểu này ẩn các giá trị bên dưới để tất cả các truy cập buộc phải dùng
API atomic.
Pointer cũng tránh
nhu cầu chuyển đổi sang
unsafe.Pointer tại call site.
Int64 và
Uint64 được
tự động căn chỉnh đến ranh giới 64-bit trong struct và dữ liệu được phân bổ,
ngay cả trên các hệ thống 32-bit.
Tra cứu PATH
Command và
LookPath không còn
cho phép kết quả từ tra cứu PATH được tìm thấy tương đối so với thư mục hiện tại.
Điều này loại bỏ một nguồn vấn đề bảo mật phổ biến
nhưng cũng có thể phá vỡ các chương trình hiện tại phụ thuộc vào việc dùng, chẳng hạn, exec.Command("prog")
để chạy một binary có tên prog (hoặc, trên Windows, prog.exe) trong thư mục hiện tại.
Xem tài liệu gói os/exec để biết
thông tin về cách cập nhật tốt nhất các chương trình như vậy.
Trên Windows, Command và LookPath hiện tuân theo
biến môi trường NoDefaultCurrentDirectoryInExePath,
giúp có thể tắt
tìm kiếm ngầm mặc định của “.” trong tra cứu PATH trên hệ thống Windows.
Các thay đổi nhỏ trong thư viện
Như thường lệ, có nhiều thay đổi và cập nhật nhỏ đối với thư viện, được thực hiện với cam kết tương thích của Go 1 trong tâm trí. Cũng có nhiều cải tiến hiệu suất khác nhau, không được liệt kê ở đây.
archive/zip
Reader
hiện bỏ qua dữ liệu không phải ZIP ở đầu tệp ZIP, khớp với hầu hết các triển khai khác.
Điều này cần thiết để đọc một số tệp Java JAR, trong số các mục đích sử dụng khác.
crypto/elliptic
Thao tác trên các điểm đường cong không hợp lệ (những điểm mà phương thức
IsOnCurve trả về false, và không bao giờ được trả về
bởi Unmarshal hoặc phương thức Curve thao tác trên một
điểm hợp lệ) luôn là hành vi không xác định và có thể dẫn đến
tấn công phục hồi khóa. Nếu một điểm không hợp lệ được cung cấp cho
Marshal,
MarshalCompressed,
Add,
Double, hoặc
ScalarMult,
chúng hiện sẽ panic.
Các thao tác ScalarBaseMult trên các đường cong P224,
P384 và P521 hiện nhanh hơn đến ba
lần, dẫn đến cải thiện tương tự trong một số thao tác ECDSA. Triển khai
P256 chung (không được tối ưu hóa cho nền tảng cụ thể) đã được
thay thế bằng một triển khai xuất phát từ mô hình được xác minh chính thức; điều này có thể
dẫn đến chậm lại đáng kể trên các nền tảng 32-bit.
crypto/rand
Read không còn buffer
dữ liệu ngẫu nhiên thu được từ hệ điều hành giữa các lần gọi. Các ứng dụng
thực hiện nhiều lần đọc nhỏ với tần suất cao có thể chọn bao bọc
Reader trong một
bufio.Reader vì lý do hiệu suất,
cẩn thận dùng
io.ReadFull
để đảm bảo không có lần đọc một phần nào xảy ra.
Trên Plan 9, Read đã được triển khai lại, thay thế thuật toán ANSI
X9.31 bằng bộ tạo key erasure nhanh.
Triển khai Prime
đã được thay đổi để chỉ sử dụng rejection sampling,
giúp loại bỏ sai lệch khi tạo các số nguyên tố nhỏ trong ngữ cảnh không mã hóa,
loại bỏ một rò rỉ timing nhỏ có thể xảy ra,
và phù hợp hơn với hành vi của BoringSSL,
đồng thời đơn giản hóa việc triển khai.
Thay đổi này tạo ra các output khác nhau cho một stream nguồn ngẫu nhiên nhất định
so với triển khai trước đó,
điều này có thể phá vỡ các kiểm thử được viết để mong đợi các kết quả cụ thể từ
các nguồn ngẫu nhiên xác định cụ thể.
Để giúp ngăn chặn các vấn đề như vậy trong tương lai,
triển khai hiện có chủ ý không xác định (non-deterministic) đối với luồng đầu vào.
crypto/tls
Tùy chọn GODEBUG tls10default=1 đã được
loại bỏ. Vẫn có thể bật TLS 1.0 phía client bằng cách đặt
Config.MinVersion.
Server và client TLS hiện từ chối các extension trùng lặp trong TLS handshake, theo yêu cầu của RFC 5246, Mục 7.4.1.4 và RFC 8446, Mục 4.2.
crypto/x509
CreateCertificate
không còn hỗ trợ tạo chứng chỉ với SignatureAlgorithm
được đặt thành MD5WithRSA.
CreateCertificate không còn chấp nhận số serial âm.
CreateCertificate sẽ không còn phát ra SEQUENCE rỗng
khi chứng chỉ được tạo ra không có extension.
Việc loại bỏ tùy chọn GODEBUG x509sha1=1,
ban đầu được lên kế hoạch cho Go 1.19, đã được lên lịch lại cho bản phát hành tương lai.
Các ứng dụng đang sử dụng nó nên chuyển đổi. Các cuộc tấn công thực tế chống lại
SHA-1 đã được chứng minh từ năm 2017 và các Cơ quan Chứng nhận (Certificate Authorities) tin cậy công khai
đã không phát hành chứng chỉ SHA-1 kể từ năm 2015.
ParseCertificate
và ParseCertificateRequest
hiện từ chối các chứng chỉ và CSR chứa các extension trùng lặp.
Các phương thức mới CertPool.Clone
và CertPool.Equal
cho phép clone một CertPool và kiểm tra sự tương đương của hai
CertPool.
Hàm mới ParseRevocationList
cung cấp một bộ phân tích cú pháp CRL nhanh hơn, an toàn hơn để sử dụng, trả về một
RevocationList.
Phân tích cú pháp CRL cũng điền vào các trường RevocationList mới
RawIssuer, Signature,
AuthorityKeyId và Extensions, bị bỏ qua bởi
CreateRevocationList.
Phương thức mới RevocationList.CheckSignatureFrom
kiểm tra rằng chữ ký trên CRL là một chữ ký hợp lệ từ một
Certificate.
Các hàm ParseCRL và
ParseDERCRL
hiện không còn được khuyến nghị (deprecated) thay cho ParseRevocationList.
Phương thức Certificate.CheckCRLSignature
không còn được khuyến nghị thay cho RevocationList.CheckSignatureFrom.
Bộ xây dựng đường dẫn của Certificate.Verify
đã được cải tổ và hiện nên tạo ra các chuỗi tốt hơn và/hoặc hiệu quả hơn trong các tình huống phức tạp.
Các ràng buộc tên (name constraints) hiện cũng được áp dụng trên các chứng chỉ không phải lá (non-leaf).
crypto/x509/pkix
Các kiểu CertificateList và
TBSCertificateList
đã được đánh dấu không còn được khuyến nghị. Chức năng CRL mới của crypto/x509
nên được dùng thay thế.
debug/elf
Các hằng số mới EM_LOONGARCH và R_LARCH_*
hỗ trợ cổng loong64.
debug/pe
Phương thức mới File.COFFSymbolReadSectionDefAux,
trả về một COFFSymbolAuxFormat5,
cung cấp quyền truy cập vào thông tin COMDAT trong các phần tệp PE.
Những thứ này được hỗ trợ bởi các hằng số IMAGE_COMDAT_* và IMAGE_SCN_* mới.
encoding/binary
Interface mới
AppendByteOrder
cung cấp các phương thức hiệu quả để thêm (append) uint16, uint32 hoặc uint64
vào một byte slice.
BigEndian và
LittleEndian hiện triển khai interface này.
Tương tự, các hàm mới
AppendUvarint và
AppendVarint
là các phiên bản hiệu quả để thêm (append) của
PutUvarint và
PutVarint.
encoding/csv
Phương thức mới
Reader.InputOffset
báo cáo vị trí đầu vào hiện tại của reader dưới dạng byte offset,
tương tự như
Decoder.InputOffset của encoding/json.
encoding/xml
Phương thức mới
Decoder.InputPos
báo cáo vị trí đầu vào hiện tại của reader dưới dạng dòng và cột,
tương tự như
Decoder.FieldPos của encoding/csv.
flag
Hàm mới
TextVar
định nghĩa một cờ với giá trị triển khai
encoding.TextUnmarshaler,
cho phép các biến cờ dòng lệnh có các kiểu như
big.Int,
netip.Addr, và
time.Time.
fmt
Các hàm mới
Append,
Appendf, và
Appendln
thêm dữ liệu được định dạng vào byte slice.
go/parser
Parser hiện nhận diện ~x như một biểu thức unary với toán tử
token.TILDE,
cho phép phục hồi lỗi tốt hơn khi một ràng buộc kiểu như ~int được dùng trong ngữ cảnh không đúng.
go/types
Các phương thức mới Func.Origin
và Var.Origin trả về
Object tương ứng của
kiểu generic cho các đối tượng Func
và Var tổng hợp được tạo trong quá trình
khởi tạo kiểu (type instantiation).
Không còn có thể tạo ra vô số lần khởi tạo kiểu
Named khác nhau nhưng giống hệt nhau qua
các lệnh gọi đệ quy đến
Named.Underlying hoặc
Named.Method.
hash/maphash
Các hàm mới
Bytes
và
String
cung cấp cách hiệu quả để hash một byte slice hoặc chuỗi đơn lẻ.
Chúng tương đương với việc dùng
Hash
tổng quát hơn với một lần ghi duy nhất, nhưng chúng tránh chi phí khởi tạo cho các đầu vào nhỏ.
html/template
Kiểu FuncMap
hiện là alias cho
FuncMap của text/template
thay vì một kiểu có tên riêng.
Điều này cho phép viết code hoạt động trên FuncMap từ cả hai ngữ cảnh.
Go 1.19.8 và mới hơn
không cho phép các action trong ECMAScript 6 template literal.
Hành vi này có thể được đảo ngược bằng cài đặt GODEBUG=jstmpllitinterp=1.
image/draw
Draw với toán tử
Src giữ nguyên
các màu alpha không nhân trước (non-premultiplied-alpha) khi cả ảnh đích và nguồn đều là
image.NRGBA
hoặc cả hai đều là image.NRGBA64.
Điều này khôi phục lại thay đổi hành vi vô tình được giới thiệu bởi một
tối ưu hóa thư viện Go 1.18; code hiện khớp với hành vi trong Go 1.17 và trước đó.
io
Kết quả của NopCloser hiện triển khai
WriterTo
khi đầu vào của nó triển khai.
Kết quả của MultiReader hiện triển khai
WriterTo vô điều kiện.
Nếu bất kỳ reader bên dưới nào không triển khai WriterTo,
nó sẽ được mô phỏng thích hợp.
mime
Chỉ trên Windows, gói mime hiện bỏ qua một mục registry
ghi rằng extension .js nên có kiểu MIME
text/plain. Đây là một
cấu hình sai vô tình phổ biến trên các hệ thống Windows. Hiệu ứng là
.js sẽ có kiểu MIME mặc định
text/javascript; charset=utf-8.
Các ứng dụng mong đợi text/plain trên Windows hiện phải
gọi rõ ràng
AddExtensionType.
mime/multipart
Trong Go 1.19.8 và mới hơn, gói này đặt giới hạn kích thước
dữ liệu MIME mà nó xử lý để bảo vệ chống lại các đầu vào độc hại.
Reader.NextPart và Reader.NextRawPart giới hạn
số header trong một phần tối đa 10000 và Reader.ReadForm giới hạn
tổng số header trong tất cả FileHeader tối đa 10000.
Các giới hạn này có thể được điều chỉnh với cài đặt GODEBUG=multipartmaxheaders.
Reader.ReadForm tiếp tục giới hạn số phần trong một form tối đa 1000.
Giới hạn này có thể được điều chỉnh với cài đặt GODEBUG=multipartmaxparts.
net
Resolver Go thuần túy hiện sẽ dùng EDNS(0) để bao gồm độ dài gói
trả lời tối đa được đề xuất, cho phép các gói trả lời chứa
tối đa 1232 byte (trước đây tối đa là 512).
Trong trường hợp không chắc xảy ra rằng điều này gây ra vấn đề với một DNS resolver
cục bộ, việc đặt biến môi trường
GODEBUG=netdns=cgo để sử dụng resolver dựa trên cgo
sẽ hoạt động.
Vui lòng báo cáo bất kỳ vấn đề nào như vậy trên bộ theo dõi
issue.
Khi một hàm hoặc phương thức trong gói net trả về lỗi “I/O timeout”,
lỗi đó hiện sẽ thỏa mãn errors.Is(err, context.DeadlineExceeded). Khi một hàm trong gói net
trả về lỗi “operation was canceled”, lỗi đó hiện sẽ
thỏa mãn errors.Is(err, context.Canceled).
Những thay đổi này nhằm giúp code dễ kiểm tra hơn
trong các trường hợp hủy context hoặc timeout khiến một hàm hoặc phương thức trong gói net
trả về lỗi, đồng thời giữ nguyên khả năng tương thích ngược cho các thông báo lỗi.
Resolver.PreferGo
hiện được triển khai trên Windows và Plan 9. Trước đây nó chỉ hoạt động trên các nền tảng Unix.
Kết hợp với
Dialer.Resolver và
Resolver.Dial, hiện
có thể viết các chương trình di động và kiểm soát tất cả các tra cứu tên DNS
khi dialing.
Gói net hiện có hỗ trợ ban đầu cho build tag netgo
trên Windows. Khi được dùng, gói sử dụng client DNS Go (như được dùng
bởi Resolver.PreferGo) thay vì hỏi Windows về
kết quả DNS. Server DNS ngược dòng mà nó tìm kiếm từ Windows
có thể chưa chính xác với cấu hình mạng hệ thống phức tạp.
net/http
ResponseWriter.WriteHeader
hiện hỗ trợ gửi các header thông tin 1xx do người dùng định nghĩa.
io.ReadCloser được trả về bởi
MaxBytesReader
hiện sẽ trả về kiểu lỗi được định nghĩa
MaxBytesError
khi giới hạn đọc của nó bị vượt quá.
HTTP client sẽ xử lý phản hồi 3xx không có
header Location bằng cách trả nó cho người gọi,
thay vì xử lý nó như một lỗi.
net/url
Hàm mới
JoinPath
và phương thức
URL.JoinPath
tạo một URL mới bằng cách nối một danh sách các phần tử đường dẫn.
Kiểu URL hiện phân biệt giữa các URL không có
authority và các URL có authority trống. Ví dụ:
http:///path có authority trống (host),
trong khi http:/path không có.
Trường mới URL
OmitHost được đặt thành true khi một
URL có authority trống.
os/exec
Một Cmd với trường Dir không rỗng
và Env nil hiện ngầm đặt biến môi trường PWD
cho tiến trình con để khớp với Dir.
Phương thức mới Cmd.Environ báo cáo
môi trường được dùng để chạy lệnh, bao gồm
biến PWD được đặt ngầm.
reflect
Phương thức Value.Bytes
hiện chấp nhận các mảng có thể địa chỉ (addressable arrays) ngoài slice.
Các phương thức Value.Len
và Value.Cap
hiện hoạt động thành công trên con trỏ đến mảng và trả về độ dài của mảng đó,
để khớp với những gì hàm built-in
len và cap làm.
regexp/syntax
Go 1.18 release candidate 1, Go 1.17.8 và Go 1.16.15 bao gồm một bản sửa lỗi bảo mật
cho parser biểu thức chính quy, khiến nó từ chối các biểu thức lồng nhau rất sâu.
Vì các bản vá phát hành Go không giới thiệu API mới,
parser trả về syntax.ErrInternalError trong trường hợp này.
Go 1.19 thêm lỗi cụ thể hơn, syntax.ErrNestingDepth,
mà parser hiện trả về thay thế.
runtime
Hàm GOROOT hiện trả về chuỗi rỗng
(thay vì "go") khi binary được build với
cờ -trimpath và biến GOROOT
không được đặt trong môi trường tiến trình.
runtime/metrics
Metric mới /sched/gomaxprocs:threads
báo cáo giá trị
runtime.GOMAXPROCS hiện tại.
Metric mới /cgo/go-to-c-calls:calls
báo cáo tổng số lệnh gọi từ Go sang C. Metric này
giống hệt với hàm
runtime.NumCgoCall.
Metric mới /gc/limiter/last-enabled:gc-cycle
báo cáo chu kỳ GC cuối cùng khi bộ giới hạn CPU GC được bật. Xem
ghi chú runtime để biết chi tiết về bộ giới hạn CPU GC.
runtime/pprof
Thời gian dừng thế giới (stop-the-world pause) đã được giảm đáng kể khi thu thập goroutine profile, giảm tác động độ trễ tổng thể đến ứng dụng.
MaxRSS hiện được báo cáo trong heap profile cho tất cả các hệ điều hành Unix
(trước đây chỉ được báo cáo cho
GOOS=android, darwin, ios và
linux).
runtime/race
Trình phát hiện race đã được nâng cấp lên phiên bản thread sanitizer
v3 trên tất cả các nền tảng được hỗ trợ
ngoại trừ windows/amd64
và openbsd/amd64, vẫn ở v2.
So với v2, nó thường nhanh hơn 1,5 đến 2 lần, sử dụng một nửa
bộ nhớ và hỗ trợ số lượng goroutine không giới hạn.
Trên Linux, trình phát hiện race hiện yêu cầu ít nhất glibc phiên bản
2.17 và GNU binutils 2.26.
Trình phát hiện race hiện được hỗ trợ trên GOARCH=s390x.
Hỗ trợ trình phát hiện race cho openbsd/amd64 đã được
loại bỏ khỏi upstream thread sanitizer, vì vậy khó có thể
được cập nhật từ v2.
runtime/trace
Khi tracing và CPU profiler được bật đồng thời, execution trace bao gồm các mẫu CPU profile như các sự kiện tức thời.
sort
Thuật toán sắp xếp đã được viết lại để sử dụng pattern-defeating quicksort, nhanh hơn cho một số kịch bản phổ biến.
Hàm mới
Find
giống như
Search
nhưng thường dễ sử dụng hơn: nó trả về thêm một boolean báo cáo liệu có tìm thấy giá trị bằng nhau không.
strconv
Quote
và các hàm liên quan hiện trích dẫn rune U+007F là \x7f,
không phải \u007f,
để nhất quán với các giá trị ASCII khác.
syscall
Trên PowerPC (GOARCH=ppc64, ppc64le),
Syscall,
Syscall6,
RawSyscall, và
RawSyscall6
hiện luôn trả về 0 cho giá trị trả về r2 thay vì
một giá trị không xác định.
Trên AIX và Solaris, Getrusage hiện được định nghĩa.
time
Phương thức mới
Duration.Abs
cung cấp cách thuận tiện và an toàn để lấy giá trị tuyệt đối của một duration,
chuyển đổi -2^63 thành 2^63-1.
(Trường hợp ranh giới này có thể xảy ra do kết quả của việc trừ thời gian gần đây từ thời gian không.)
Phương thức mới
Time.ZoneBounds
trả về thời gian bắt đầu và kết thúc của múi giờ có hiệu lực tại một thời điểm nhất định.
Nó có thể được dùng trong một vòng lặp để liệt kê tất cả các chuyển đổi múi giờ đã biết tại một vị trí nhất định.