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.Int64atomic.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 testgo 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=amd64GOARCH=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. Int64Uint64 đượ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

CommandLookPath 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, CommandLookPath 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, P384P521 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.

ParseCertificateParseCertificateRequest 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.CloneCertPool.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, AuthorityKeyIdExtensions, 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 ParseCRLParseDERCRL 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 CertificateListTBSCertificateList đã đượ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_LOONGARCHR_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_*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. BigEndianLittleEndian hiện triển khai interface này.

Tương tự, các hàm mới AppendUvarintAppendVarint là các phiên bản hiệu quả để thêm (append) của PutUvarintPutVarint.

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.OriginVar.Origin trả về Object tương ứng của kiểu generic cho các đối tượng FuncVar 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 BytesString 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.NextPartReader.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.ResolverResolver.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.LenValue.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 lencap 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, ioslinux).

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/amd64openbsd/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.