Go 1.20 發行說明
Go 1.20 簡介
最新的 Go 版本 1.20 在 Go 1.19 釋出六個月後到來。其大部分更改都在工具鏈、執行時和庫的實現中。一如既往,此版本保持了 Go 1 相容性承諾。我們預計幾乎所有 Go 程式都將像以前一樣繼續編譯和執行。
語言變化
Go 1.20 包含四項語言更改。
Go 1.17 添加了從切片到陣列指標的轉換。Go 1.20 將其擴充套件為允許從切片到陣列的轉換:給定切片 x,現在可以編寫 [4]byte(x) 而不是 *(*[4]byte)(x)。
unsafe 包定義了三個新函式 SliceData、String 和 StringData。與 Go 1.17 的 Slice 一起,這些函式現在提供了構造和解構切片和字串值的完整能力,而無需依賴它們的精確表示。
規範現在定義了結構體值逐欄位進行比較,按照它們在結構體型別定義中出現的順序考慮欄位,並在第一個不匹配處停止。以前的規範可能被解讀為所有欄位都需要在第一個不匹配之後進行比較。類似地,規範現在定義了陣列值逐元素進行比較,按遞增索引順序。在這兩種情況下,差異影響了某些比較是否必須引發恐慌。現有程式不變:新的規範措辭描述了實現一直以來的做法。
可比較型別(例如普通介面)現在可以滿足 comparable 約束,即使型別引數不是嚴格可比較的(比較可能在執行時引發恐慌)。這使得可以使用非嚴格可比較的型別引數(例如介面型別,或包含介面型別的複合型別)例項化受 comparable 約束的型別引數(例如用於使用者定義的泛型對映鍵的型別引數)。
移植
Windows
Go 1.20 是最後一個可以在 Windows 7、8、Server 2008 和 Server 2012 的任何版本上執行的版本。Go 1.21 將至少需要 Windows 10 或 Server 2016。
Darwin 和 iOS
Go 1.20 是最後一個可以在 macOS 10.13 High Sierra 或 10.14 Mojave 上執行的版本。Go 1.21 將需要 macOS 10.15 Catalina 或更高版本。
FreeBSD/RISC-V
Go 1.20 添加了對 RISC-V 上的 FreeBSD 的實驗性支援 (GOOS=freebsd, GOARCH=riscv64)。
工具
Go 命令
目錄 $GOROOT/pkg 不再儲存標準庫的預編譯包歸檔:go install 不再寫入它們,go build 不再檢查它們,Go 發行版也不再隨附它們。相反,標準庫中的包會根據需要構建並快取到構建快取中,就像 GOROOT 之外的包一樣。此更改減少了 Go 發行版的大小,並避免了使用 cgo 的包的 C 工具鏈偏差。
go test -json 的實現得到了改進,使其更加健壯。執行 go test -json 的程式不需要任何更新。直接呼叫 go tool test2json 的程式現在應該使用 -v=test2json 執行測試二進位制檔案(例如,go test -v=test2json 或 ./pkg.test -test.v=test2json),而不是普通的 -v。
go test -json 的一個相關更改是在每個測試程式執行開始時新增一個 Action 設定為 start 的事件。當使用 go 命令執行多個測試時,這些啟動事件保證以與命令列上命名的包相同的順序發出。
go 命令現在定義了架構特性構建標籤,例如 amd64.v2,以允許根據特定架構特性的存在或不存在選擇包實現檔案。詳情請參閱 go help buildconstraint。
go 子命令現在接受 -C <dir>,用於在執行命令之前更改目錄到 <dir>,這對於需要在多個不同模組中執行命令的指令碼可能很有用。
go build 和 go test 命令不再接受 -i 標誌,該標誌已 自 Go 1.16 起棄用。
go generate 命令現在接受 -skip <pattern> 來跳過匹配 <pattern> 的 //go:generate 指令。
go test 命令現在接受 -skip <pattern> 來跳過匹配 <pattern> 的測試、子測試或示例。
當主模組位於 GOPATH/src 中時,go install 不再將非 main 包的庫安裝到 GOPATH/pkg,並且 go list 不再報告此類包的 Target 欄位。(在模組模式下,編譯的包只儲存在構建快取中,但一個 bug 導致 GOPATH 安裝目標意外地仍然有效。)
go build、go install 和其他與構建相關的命令現在支援 -pgo 標誌,該標誌啟用配置檔案引導最佳化,這在下面的編譯器部分中有更詳細的描述。-pgo 標誌指定配置檔案的檔案路徑。指定 -pgo=auto 會導致 go 命令在主包的目錄中搜索名為 default.pgo 的檔案,如果存在則使用它。此模式目前要求在命令列上指定單個主包,但我們計劃在未來的版本中取消此限制。指定 -pgo=off 會關閉配置檔案引導最佳化。
go build、go install 和其他與構建相關的命令現在支援 -cover 標誌,該標誌使用程式碼覆蓋率檢測構建指定目標。這在下面的覆蓋率部分中有更詳細的描述。
go version
go version -m 命令現在支援讀取更多型別的 Go 二進位制檔案,最值得注意的是,使用 go build -buildmode=c-shared 構建的 Windows DLL 和沒有執行許可權的 Linux 二進位制檔案。
Cgo
在沒有 C 工具鏈的系統上,go 命令現在預設停用 cgo。更具體地說,當 CGO_ENABLED 環境變數未設定、CC 環境變數未設定,並且在路徑中找不到預設的 C 編譯器(通常是 clang 或 gcc)時,CGO_ENABLED 預設值為 0。與往常一樣,可以透過顯式設定 CGO_ENABLED 來覆蓋預設值。
預設更改最重要的影響是,當 Go 安裝在沒有 C 編譯器的系統上時,它現在將使用純 Go 構建來構建標準庫中使用 cgo 的包,而不是使用預分發的包歸檔(如上文所述已刪除)或嘗試使用 cgo 並失敗。這使得 Go 在某些最小的容器環境以及 macOS 上工作得更好,在 macOS 上,自 Go 1.16 以來,基於 cgo 的包就沒有使用過預分發的包歸檔。
標準庫中使用 cgo 的包是 net、os/user 和 plugin。在 macOS 上,net 和 os/user 包已被重寫為不使用 cgo:現在 cgo 和非 cgo 構建以及交叉編譯構建都使用相同的程式碼。在 Windows 上,net 和 os/user 包從未使用過 cgo。在其他系統上,停用 cgo 的構建將使用這些包的純 Go 版本。
一個結果是,在 macOS 上,如果使用 net 包的 Go 程式碼使用 -buildmode=c-archive 構建,將生成的歸檔連結到 C 程式需要在連結 C 程式碼時傳遞 -lresolv。
在 macOS 上,競爭檢測器已被重寫為不使用 cgo:啟用競爭檢測器的程式可以在沒有 Xcode 的情況下構建和執行。在 Linux 和其他 Unix 系統以及 Windows 上,需要主機 C 工具鏈才能使用競爭檢測器。
覆蓋率
Go 1.20 支援收集程式(應用程式和整合測試)的程式碼覆蓋率配置檔案,而不僅僅是單元測試。
要收集程式的覆蓋率資料,請使用 go build 的 -cover 標誌構建它,然後將環境變數 GOCOVERDIR 設定為覆蓋率配置檔案的輸出目錄,然後執行生成的二進位制檔案。有關如何入門的更多資訊,請參閱“整合測試覆蓋率”著陸頁。有關設計和實現的詳細資訊,請參閱提案。
Vet
改進了對巢狀函式捕獲迴圈變數的檢測
vet 工具現在報告在子測試函式體內呼叫 T.Parallel() 後對迴圈變數的引用。此類引用可能會觀察到來自不同迭代的變數值(通常導致測試用例被跳過)或由於未同步的併發訪問而導致無效狀態。
該工具還在更多地方檢測引用錯誤。以前它只考慮迴圈體的最後一條語句,但現在它遞迴地檢查 if、switch 和 select 語句中的最後一條語句。
不正確時間格式的新診斷
vet 工具現在報告使用時間格式 2006-02-01 (yyyy-dd-mm) 與 Time.Format 和 time.Parse。這種格式不出現在常見日期標準中,但在嘗試使用 ISO 8601 日期格式 (yyyy-mm-dd) 時經常錯誤地使用。
執行時
垃圾收集器的一些內部資料結構進行了重新組織,以提高空間和 CPU 效率。此更改減少了記憶體開銷並將整體 CPU 效能提高了高達 2%。
在某些情況下,垃圾收集器在 goroutine 輔助方面的行為不再那麼不穩定。
Go 1.20 添加了一個新的 runtime/coverage 包,其中包含用於從透過 os.Exit() 不終止的長時間執行和/或伺服器程式在執行時寫入覆蓋率配置檔案資料的 API。
編譯器
Go 1.20 添加了對配置檔案引導最佳化 (PGO) 的預覽支援。PGO 使工具鏈能夠根據執行時配置檔案資訊執行應用程式和工作負載特定的最佳化。目前,編譯器支援 pprof CPU 配置檔案,這些配置檔案可以透過常規方式收集,例如 runtime/pprof 或 net/http/pprof 包。要啟用 PGO,如上文所述,透過 -pgo 標誌將 pprof 配置檔案檔案的路徑傳遞給 go build。Go 1.20 使用 PGO 在熱呼叫站點更積極地行內函數。一組代表性 Go 程式的基準測試表明,啟用配置檔案引導的內聯最佳化可將效能提高約 3-4%。有關詳細文件,請參閱 PGO 使用者指南。我們計劃在未來版本中新增更多配置檔案引導最佳化。請注意,配置檔案引導最佳化是一個預覽功能,因此請謹慎使用。
Go 1.20 編譯器將其前端升級為使用一種處理編譯器內部資料的新方法,這修復了幾個泛型型別問題,並啟用了泛型函式和方法中的型別宣告。
編譯器現在預設透過編譯器錯誤拒絕匿名介面迴圈。這些是由於嵌入式介面的複雜使用而產生的,並且一直存在微妙的正確性問題,但我們沒有證據表明它們在實踐中被實際使用。假設沒有使用者報告受此更改的不利影響,我們計劃更新 Go 1.22 的語言規範以正式禁止它們,以便工具作者也可以停止支援它們。
Go 1.18 和 1.19 在構建速度方面出現了退步,這主要是由於添加了對泛型的支援和後續工作。Go 1.20 將構建速度提高了高達 10%,使其恢復到 Go 1.17 的水平。相對於 Go 1.19,生成的程式碼效能也普遍略有改善。
連結器
在 Linux 上,連結器現在在連結時選擇 glibc 或 musl 的動態直譯器。
在 Windows 上,Go 連結器現在支援基於 LLVM 的現代 C 工具鏈。
Go 1.20 使用 go: 和 type: 字首表示編譯器生成的符號,而不是 go. 和 type.。這避免了名稱以 go. 開頭的使用者包的混淆。debug/gosym 包理解 Go 1.20 及更高版本構建的二進位制檔案的這種新命名約定。
引導
從原始碼構建 Go 版本且未設定 GOROOT_BOOTSTRAP 時,Go 的早期版本會在目錄 $HOME/go1.4(Windows 上為 %HOMEDRIVE%%HOMEPATH%\go1.4)中查詢 Go 1.4 或更高版本的引導工具鏈。Go 1.18 和 Go 1.19 首先查詢 $HOME/go1.17 或 $HOME/sdk/go1.17,然後再回退到 $HOME/go1.4,以期望在引導 Go 1.20 時需要 Go 1.17。Go 1.20 確實需要 Go 1.17 版本進行引導,但我們意識到我們應該採用引導工具鏈的最新點發布版本,因此它需要 Go 1.17.13。Go 1.20 會查詢 $HOME/go1.17.13 或 $HOME/sdk/go1.17.13,然後再回退到 $HOME/go1.4(以支援那些硬編碼路徑 $HOME/go1.4 但已在那裡安裝了更新的 Go 工具鏈的系統)。將來,我們計劃大約每年將引導工具鏈向前推進一次,特別是我們預計 Go 1.22 將需要 Go 1.20 的最終點發布版本進行引導。
標準庫
新的 crypto/ecdh 包
Go 1.20 添加了一個新的 crypto/ecdh 包,以提供對 NIST 曲線和 Curve25519 上的橢圓曲線 Diffie-Hellman 金鑰交換的顯式支援。
程式應使用 crypto/ecdh 代替 crypto/elliptic 中較低級別的 ECDH 功能,對於更高階的用例則使用第三方模組。
包裝多個錯誤
Go 1.20 擴充套件了對錯誤包裝的支援,允許一個錯誤包裝多個其他錯誤。
錯誤 e 可以透過提供返回 []error 的 Unwrap 方法來包裝多個錯誤。
errors.Is 和 errors.As 函式已更新以檢查多重包裝的錯誤。
fmt.Errorf 函式現在支援 %w 格式動詞的多次出現,這將導致它返回一個包裝所有這些錯誤運算元的錯誤。
新函式 errors.Join 返回一個包裝錯誤列表的錯誤。
HTTP ResponseController
新的 "net/http".ResponseController 型別提供對 "net/http".ResponseWriter 介面未處理的擴充套件的每請求功能的訪問。
以前,我們透過定義 ResponseWriter 可以實現的可選介面(例如 Flusher)來新增新的每請求功能。這些介面不可發現且使用笨拙。
ResponseController 型別提供了一種更清晰、更易於發現的方式來新增每處理程式控制元件。Go 1.20 中也添加了兩個此類控制元件:SetReadDeadline 和 SetWriteDeadline,它們允許設定每請求的讀取和寫入截止時間。例如:
func RequestHandler(w ResponseWriter, r *Request) {
rc := http.NewResponseController(w)
rc.SetWriteDeadline(time.Time{}) // disable Server.WriteTimeout when sending a large response
io.Copy(w, bigData)
}
新的 ReverseProxy Rewrite 鉤子
httputil.ReverseProxy 轉發代理包含一個新的 Rewrite 鉤子函式,取代了之前的 Director 鉤子。
Rewrite 鉤子接受一個 ProxyRequest 引數,其中包括代理收到的入站請求和它將傳送的出站請求。與只對出站請求操作的 Director 鉤子不同,這允許 Rewrite 鉤子避免某些惡意入站請求可能導致鉤子新增的標頭在轉發之前被刪除的情況。請參閱 問題 #50580。
ProxyRequest.SetURL 方法將出站請求路由到提供的目標,並取代了 NewSingleHostReverseProxy 函式。與 NewSingleHostReverseProxy 不同,SetURL 還設定出站請求的 Host 標頭。
ProxyRequest.SetXForwarded 方法設定出站請求的 X-Forwarded-For、X-Forwarded-Host 和 X-Forwarded-Proto 標頭。當使用 Rewrite 時,這些標頭預設不會新增。
使用這些功能的 Rewrite 鉤子示例如下:
proxyHandler := &httputil.ReverseProxy{
Rewrite: func(r *httputil.ProxyRequest) {
r.SetURL(outboundURL) // Forward request to outboundURL.
r.SetXForwarded() // Set X-Forwarded-* headers.
r.Out.Header.Set("X-Additional-Header", "header set by the proxy")
},
}
當傳入請求沒有 User-Agent 標頭時,ReverseProxy 不再向轉發請求新增 User-Agent 標頭。
對庫的微小更改
一如既往,庫中進行了各種小的更改和更新,始終牢記 Go 1 的相容性承諾。還有各種未在此處列出的效能改進。
archive/tar
當設定 GODEBUG=tarinsecurepath=0 環境變數時,Reader.Next 方法現在將為檔名是絕對路徑、引用當前目錄之外的位置、包含無效字元或(在 Windows 上)是保留名稱(如 NUL)的條目返回錯誤 ErrInsecurePath。Go 的未來版本可能會預設停用不安全路徑。
archive/zip
當設定 GODEBUG=zipinsecurepath=0 環境變數時,NewReader 現在將在開啟包含檔名是絕對路徑、引用當前目錄之外的位置、包含無效字元或(在 Windows 上)是保留名稱(如 NUL)的任何檔案的歸檔時返回錯誤 ErrInsecurePath。Go 的未來版本可能會預設停用不安全路徑。
從包含檔案資料的目錄檔案讀取現在將返回錯誤。zip 規範不允許目錄檔案包含檔案資料,因此此更改僅影響從無效歸檔讀取。
bytes
新的 CutPrefix 和 CutSuffix 函式類似於 TrimPrefix 和 TrimSuffix,但也會報告字串是否被修剪。
新的 Clone 函式分配一個位元組切片的副本。
context
新的 WithCancelCause 函式提供了一種使用給定錯誤取消上下文的方法。可以透過呼叫新的 Cause 函式檢索該錯誤。
crypto/ecdsa
在使用支援的曲線時,所有操作現在都在恆定時間內實現。這導致 CPU 時間增加了 5% 到 30%,主要影響 P-384 和 P-521。
新的 PrivateKey.ECDH 方法將 ecdsa.PrivateKey 轉換為 ecdh.PrivateKey。
crypto/ed25519
PrivateKey.Sign 方法和 VerifyWithOptions 函式現在支援使用 Ed25519ph 簽名預雜湊訊息,由返回 crypto.SHA512 的 Options.HashFunc 指示。它們現在還支援帶上下文的 Ed25519ctx 和 Ed25519ph,由設定新的 Options.Context 欄位指示。
crypto/rsa
新欄位 OAEPOptions.MGFHash 允許為 OAEP 解密單獨配置 MGF1 雜湊。
crypto/rsa 現在使用新的、更安全的、恆定時間後端。這導致解密操作的 CPU 執行時增加了大約 15%(amd64 上的 RSA-2048)到 45%(arm64 上的 RSA-4096),在 32 位架構上更多。加密操作比以前慢大約 20 倍(但仍然比解密快 5-10 倍)。預計效能將在未來版本中得到改善。程式不得修改或手動生成 PrecomputedValues 的欄位。
crypto/subtle
新函式 XORBytes 將兩個位元組切片進行異或操作。
crypto/tls
解析後的證書現在在所有主動使用該證書的客戶端之間共享。在對伺服器或共享其證書鏈任何部分的伺服器集合進行許多併發連線的程式中,記憶體節省可能非常顯著。
對於由於證書驗證失敗導致的握手失敗,TLS 客戶端和伺服器現在返回新型別 CertificateVerificationError 的錯誤,其中包括提供的證書。
crypto/x509
ParsePKCS8PrivateKey 和 MarshalPKCS8PrivateKey 現在支援 *crypto/ecdh.PrivateKey 型別的金鑰。ParsePKIXPublicKey 和 MarshalPKIXPublicKey 現在支援 *crypto/ecdh.PublicKey 型別的金鑰。解析 NIST 曲線金鑰仍然返回 *ecdsa.PublicKey 和 *ecdsa.PrivateKey 型別的值。使用它們新的 ECDH 方法將其轉換為 crypto/ecdh 型別。
新函式 SetFallbackRoots 允許程式定義一組備用根證書,以防在執行時作業系統驗證程式或標準平臺根包不可用。它最常與新包 golang.org/x/crypto/x509roots/fallback 一起使用,該包將提供最新的根包。
debug/elf
嘗試使用 Section.Data 或 Section.Open 返回的讀取器從 SHT_NOBITS 部分讀取現在會返回錯誤。
為 LoongArch 系統定義了額外的 R_LARCH_* 常量。
為 PPC64 ELFv2 重定位定義了額外的 R_PPC64_* 常量。
R_PPC64_SECTOFF_LO_DS 的常量值已更正,從 61 到 62。
debug/gosym
由於 Go 的符號命名約定發生了變化,處理 Go 二進位制檔案的工具應使用 Go 1.20 的 debug/gosym 包來透明地處理舊和新的二進位制檔案。
debug/pe
為 RISC-V 系統定義了額外的 IMAGE_FILE_MACHINE_RISCV* 常量。
encoding/binary
ReadVarint 和 ReadUvarint 函式現在在讀取部分值後將返回 io.ErrUnexpectedEOF,而不是 io.EOF。
encoding/xml
新的 Encoder.Close 方法可以在編碼完成後檢查未關閉的元素。
解碼器現在拒絕帶有多個冒號的元素和屬性名稱,例如 <a:b:c>,以及解析為空字串的名稱空間,例如 xmlns:a=""。
解碼器現在拒絕在開始標籤和結束標籤中使用不同名稱空間字首的元素,即使這些字首都表示相同的名稱空間。
errors
新的 Join 函式返回一個包裝錯誤列表的錯誤。
fmt
Errorf 函式支援 %w 格式動詞的多次出現,返回一個解包為所有 %w 引數列表的錯誤。
新的 FormatString 函式恢復與 State 對應的格式化指令,這在 Formatter 實現中可能很有用。
go/ast
新的 RangeStmt.Range 欄位記錄 range 語句中 range 關鍵字的位置。
新的 File.FileStart 和 File.FileEnd 欄位記錄整個原始檔的開始和結束位置。
go/token
新的 FileSet.RemoveFile 方法從 FileSet 中刪除檔案。長時間執行的程式可以使用此方法釋放與其不再需要的檔案相關的記憶體。
go/types
新的 Satisfies 函式報告型別是否滿足約束。此更改與新的語言語義一致,該語義區分滿足約束和實現介面。
html/template
Go 1.20.3 及更高版本不允許 ECMAScript 6 模板字面量中的操作。此行為可以透過 GODEBUG=jstmpllitinterp=1 設定恢復。
io
新的 OffsetWriter 包裝了一個底層 WriterAt,並提供了 Seek、Write 和 WriteAt 方法,這些方法透過固定量調整其有效的寫入偏移位置。
io/fs
math/big
math/big 包的廣泛範圍和輸入相關的計時使其不適合實現加密。標準庫中的加密包不再在攻擊者控制的輸入上呼叫非平凡的 Int 方法。將來,判斷 math/big 中的錯誤是否被視為安全漏洞將取決於其對標準庫的更廣泛影響。
math/rand
math/rand 包現在會自動使用隨機值播種全域性隨機數生成器(由 Float64 和 Int 等頂級函式使用),並且頂級 Seed 函式已被棄用。需要可重現的隨機數序列的程式應優先使用 rand.New(rand.NewSource(seed)) 分配自己的隨機源。
需要早期一致全域性播種行為的程式可以在其環境中設定 GODEBUG=randautoseed=0。
頂級 Read 函式已被棄用。在幾乎所有情況下,crypto/rand.Read 更合適。
mime
ParseMediaType 函式現在允許重複的引數名稱,只要名稱的值相同。
mime/multipart
Reader 型別的方法現在包裝了底層 io.Reader 返回的錯誤。
在 Go 1.19.8 及更高版本中,此包限制了它處理的 MIME 資料的大小,以防止惡意輸入。Reader.NextPart 和 Reader.NextRawPart 將一個部分的標頭數量限制為 10000,Reader.ReadForm 將所有 FileHeaders 中標頭的總數限制為 10000。這些限制可以透過 GODEBUG=multipartmaxheaders 設定進行調整。Reader.ReadForm 進一步將表單中的部分數量限制為 1000。此限制可以透過 GODEBUG=multipartmaxparts 設定進行調整。
net
LookupCNAME 函式現在在存在 CNAME 記錄時始終返回 CNAME 記錄的內容。以前在 Unix 系統上以及使用純 Go 解析器時,如果 CNAME 記錄引用一個沒有 A、AAAA 或 CNAME 記錄的名稱,LookupCNAME 將返回錯誤。此更改修改了 LookupCNAME 以匹配 Windows 上的先前行為,允許 LookupCNAME 在 CNAME 存在時成功。
Interface.Flags 現在包含新標誌 FlagRunning,表示操作活動的介面。一個已管理配置但未活動的介面(例如,因為網線未連線)將設定 FlagUp 但不設定 FlagRunning。
新的 Dialer.ControlContext 欄位包含一個回撥函式,類似於現有的 Dialer.Control 鉤子,它額外接受撥號上下文作為引數。當 ControlContext 不為 nil 時,Control 將被忽略。
Go DNS 解析器識別 trust-ad 解析器選項。當 resolv.conf 中設定 options trust-ad 時,Go 解析器將在 DNS 查詢中設定 AD 位。解析器不使用響應中的 AD 位。
DNS 解析將檢測 /etc/nsswitch.conf 的更改並在檔案更改時重新載入。檢查最多每五秒進行一次,與以前處理 /etc/hosts 和 /etc/resolv.conf 的方式相同。
net/http
ResponseWriter.WriteHeader 函式現在支援傳送 1xx 狀態碼。
新的 Server.DisableGeneralOptionsHandler 配置設定允許停用預設的 OPTIONS * 處理程式。
新的 Transport.OnProxyConnectResponse 鉤子在 Transport 從代理收到 CONNECT 請求的 HTTP 響應時呼叫。
HTTP 伺服器現在接受包含正文的 HEAD 請求,而不是將其拒絕為無效請求。
net/http 函式返回的 HTTP/2 流錯誤可以使用 errors.As 轉換為 golang.org/x/net/http2.StreamError。
cookie 名稱的前導和尾隨空格將被修剪,而不是被拒絕為無效。例如,現在接受“name =value”的 cookie 設定為設定 cookie“name”。
Expires 欄位為空的 Cookie 現在被認為是有效的。Cookie.Valid 僅在設定 Expires 時檢查。
net/netip
新的 IPv6LinkLocalAllRouters 和 IPv6Loopback 函式是 net.IPv6loopback 和 net.IPv6linklocalallrouters 在 net/netip 中的等價物。
os
在 Windows 上,名稱 NUL 在 Mkdir 和 Stat 中不再被視為特殊情況。
在 Windows 上,File.Stat 現在在檔案是目錄時使用檔案控制代碼檢索屬性。以前它會使用傳遞給 Open 的路徑,如果檔案已被移動或替換,該路徑可能不再表示檔案控制代碼表示的檔案。此更改修改了 Open 以在不使用 FILE_SHARE_DELETE 訪問許可權的情況下開啟目錄,這與常規檔案的行為匹配。
在 Windows 上,File.Seek 現在支援查詢目錄的開頭。
os/exec
新的 Cmd 欄位 Cancel 和 WaitDelay 指定當其關聯的 Context 被取消或其程序在子程序仍持有 I/O 管道開啟時退出時 Cmd 的行為。
path/filepath
新的 IsLocal 函式報告路徑是否在詞法上相對於目錄。例如,如果 IsLocal(p) 為 true,則 Open(p) 將引用一個詞法上位於當前目錄下的檔案。
reflect
新的 Value.Comparable 和 Value.Equal 方法可用於比較兩個 Value 的相等性。Comparable 報告對於給定 Value 接收器,Equal 是否是有效操作。
新的 Value.Grow 方法擴充套件切片以保證另一個 n 個元素的空間。
新的 Value.SetZero 方法將值設定為其型別的零值。
Go 1.18 引入了 Value.SetIterKey 和 Value.SetIterValue 方法。這些是最佳化:v.SetIterKey(it) 旨在等效於 v.Set(it.Key())。實現錯誤地省略了對未匯出欄位使用的檢查,而未最佳化形式中存在該檢查。Go 1.20 糾正了這些方法以包含未匯出欄位檢查。
regexp
Go 1.19.2 和 Go 1.18.7 包含一個針對正則表示式解析器的安全修復,使其拒絕會消耗過多記憶體的超大表達式。由於 Go 補丁版本不引入新的 API,解析器在這種情況下返回 syntax.ErrInternalError。Go 1.20 添加了一個更具體的錯誤 syntax.ErrLarge,解析器現在返回該錯誤。
runtime/cgo
Go 1.20 添加了新的 Incomplete 標記型別。cgo 生成的程式碼將使用 cgo.Incomplete 來標記不完整的 C 型別。
runtime/metrics
Go 1.20 添加了新的支援指標,包括當前的 GOMAXPROCS 設定 (/sched/gomaxprocs:threads)、執行的 cgo 呼叫次數 (/cgo/go-to-c-calls:calls)、總互斥鎖阻塞時間 (/sync/mutex/wait/total:seconds) 以及垃圾回收中花費的各種時間度量。
基於時間的直方圖指標現在精度較低,但佔用記憶體少得多。
runtime/pprof
互斥鎖配置檔案樣本現在已預先縮放,修復瞭如果取樣率在執行期間發生變化,舊互斥鎖配置檔案樣本將被錯誤縮放的問題。
在 Windows 上收集的配置檔案現在包含記憶體對映資訊,修復了位置無關二進位制檔案的符號化問題。
runtime/trace
垃圾收集器的後臺清掃器現在讓步的頻率更低,從而在執行跟蹤中產生更少的多餘事件。
strings
新的 CutPrefix 和 CutSuffix 函式類似於 TrimPrefix 和 TrimSuffix,但也會報告字串是否被修剪。
sync
新的 Map 方法 Swap、CompareAndSwap 和 CompareAndDelete 允許原子更新現有對映條目。
syscall
在 FreeBSD 上,已刪除 FreeBSD 11 及更早版本所需的相容性填充。
在 Linux 上,為 SysProcAttr.Cloneflags 欄位定義了額外的 CLONE_* 常量。
在 Linux 上,新的 SysProcAttr.CgroupFD 和 SysProcAttr.UseCgroupFD 欄位提供了一種將子程序放入特定 cgroup 的方法。
testing
新方法 B.Elapsed 報告基準測試的當前經過時間,這對於計算與 ReportMetric 一起報告的速率可能很有用。
從傳遞給 T.Cleanup 的函式中呼叫 T.Run 從未明確定義,現在將導致恐慌。
time
新的時間佈局常量 DateTime、DateOnly 和 TimeOnly 為公共 Go 原始碼調查中使用的三種最常見佈局字串提供了名稱。
新的 Time.Compare 方法比較兩個時間。
Parse 現在忽略輸入中的亞納秒精度,而不是將這些數字報告為錯誤。
Time.MarshalJSON 方法現在對 RFC 3339 的遵守更加嚴格。
unicode/utf16
新的 AppendRune 函式將給定符文的 UTF-16 編碼附加到 uint16 切片,類似於 utf8.AppendRune。