Go 1.18 釋出說明

Go 1.18 簡介

最新的 Go 版本 1.18 是一個重要版本,包含語言、工具鏈實現、執行時和庫的更改。Go 1.18 在 Go 1.17 釋出七個月後到來。與往常一樣,該版本保持了 Go 1 相容性承諾。我們預計幾乎所有 Go 程式都將像以前一樣繼續編譯和執行。

語言變化

泛型

Go 1.18 包含了 型別引數提案 中描述的泛型功能的實現。這包括語言的重大(但完全向後相容)更改。

這些新的語言更改需要大量尚未在生產環境中進行大量測試的新程式碼。只有當更多人編寫和使用泛型程式碼時,這種情況才會發生。我們相信此功能實現良好且質量高。然而,與 Go 的大多數方面不同,我們無法用實際經驗來支援這種信念。因此,雖然我們鼓勵在有意義的地方使用泛型,但在生產環境中部署泛型程式碼時,請謹慎使用。

雖然我們相信新的語言特性設計良好且規範清晰,但我們可能犯了錯誤。我們想強調的是,Go 1 相容性保證 宣告“如果需要解決規範中的不一致或不完整,解決問題可能會影響現有程式的含義或合法性。我們保留解決此類問題的權利,包括更新實現。”它還宣告“如果編譯器或庫存在違反規範的錯誤,如果修復該錯誤,依賴於該錯誤行為的程式可能會中斷。我們保留修復此類錯誤的權利。”換句話說,可能會有一些使用泛型的程式碼在 1.18 版本中可以工作,但在後續版本中會中斷。我們不計劃也不期望進行任何此類更改。然而,在未來的版本中中斷 1.18 程式可能由於我們目前無法預見的原因而變得必要。我們將盡可能減少任何此類中斷,但我們不能保證中斷為零。

以下是最顯著的更改列表。有關更全面的概述,請參閱 提案。有關詳細資訊,請參閱 語言規範

  • 函式型別宣告 的語法現在接受 型別引數
  • 可以透過在引數化函式和型別後新增方括號中的型別引數列表來例項化它們。
  • 新標記 ~ 已新增到 運算子和標點符號 集中。
  • 介面型別 的語法現在允許嵌入任意型別(不僅僅是介面的型別名稱)以及聯合和 ~T 型別元素。此類介面只能用作型別約束。介面現在定義了一組型別以及一組方法。
  • 新的 預宣告識別符號 any 是空介面的別名。它可以用作 interface{} 的替代。
  • 新的 預宣告識別符號 comparable 是一個介面,表示所有可以使用 ==!= 進行比較的型別集合。它只能用作(或嵌入在)型別約束中。

有三個使用泛型的實驗性包可能很有用。這些包位於 x/exp 倉庫中;它們的 API 不受 Go 1 保證的覆蓋,並且可能會隨著我們對泛型經驗的增加而更改。

golang.org/x/exp/constraints

對泛型程式碼有用的約束,例如 constraints.Ordered

golang.org/x/exp/slices

在任何元素型別的切片上操作的泛型函式集合。

golang.org/x/exp/maps

在任何鍵或元素型別的對映上操作的泛型函式集合。

當前的泛型實現有以下已知限制:

  • Go 編譯器無法處理泛型函式或方法中的型別宣告。我們希望在未來版本中提供對此功能的支援。
  • Go 編譯器不接受帶有預宣告函式 realimagcomplex 的型別引數型別的引數。我們希望在未來版本中消除此限制。
  • Go 編譯器僅支援在型別引數型別 P 的值 x 上呼叫方法 m,如果 mP 的約束介面顯式宣告。類似地,方法值 x.m 和方法表示式 P.m 也僅在 mP 顯式宣告時才受支援,即使 m 可能是 P 的方法集中的成員,因為 P 中的所有型別都實現了 m。我們希望在未來版本中消除此限制。
  • Go 編譯器不支援訪問結構欄位 x.f,其中 x 是型別引數型別,即使型別引數型別集中的所有型別都具有欄位 f。我們可能會在未來版本中消除此限制。
  • 不允許將型別引數或指向型別引數的指標作為未命名欄位嵌入到結構型別中。類似地,不允許將型別引數嵌入到介面型別中。目前尚不清楚是否會允許這些操作。
  • 具有多個項的聯合元素可能不包含具有非空方法集的介面型別。目前尚不清楚是否會允許此操作。

泛型也代表著 Go 生態系統的一次重大變革。雖然我們已經更新了幾個核心工具以支援泛型,但還有很多工作要做。其餘工具、文件和庫需要時間來跟上這些語言更改。

Bug 修復

Go 1.18 編譯器現在會正確報告函式文字內部設定但從未使用過的變數的 declared but not used 錯誤。在 Go 1.18 之前,編譯器在這種情況下不會報告錯誤。這修復了長期存在的編譯器問題 #8560。由於此更改,(可能不正確的)程式可能無法再編譯。必要的修復很簡單:如果程式確實不正確,則修復它,或者使用有問題的變數,例如將其分配給空白識別符號 _。由於 go vet 總是指出此錯誤,受影響的程式數量可能非常少。

Go 1.18 編譯器現在在將 rune 常量表達式(例如 '1' << 32)作為引數傳遞給預宣告函式 printprintln 時報告溢位,這與使用者定義函式的行為一致。在 Go 1.18 之前,編譯器在這種情況下不會報告錯誤,而是靜默接受此類常量引數,如果它們適合 int64。由於此更改,(可能不正確的)程式可能無法再編譯。必要的修復很簡單:如果程式確實不正確,則修復它,或者將有問題的引數顯式轉換為正確的型別。由於 go vet 總是指出此錯誤,受影響的程式數量可能非常少。

移植

AMD64

Go 1.18 引入了新的 GOAMD64 環境變數,該變數在編譯時選擇 AMD64 架構的最小目標版本。允許的值為 v1v2v3v4。每個更高級別都需要並利用額外的處理器功能。詳細說明可以在 此處 找到。

GOAMD64 環境變數預設為 v1

RISC-V

Linux 上的 64 位 RISC-V 架構(linux/riscv64 埠)現在支援 c-archivec-shared 構建模式。

Linux

Go 1.18 需要 Linux 核心版本 2.6.32 或更高版本。

Windows

windows/armwindows/arm64 埠現在支援非協作搶佔,將該功能引入所有四個 Windows 埠,這有望解決在呼叫長時間阻塞的 Win32 函式時遇到的微妙錯誤。

iOS

在 iOS(ios/arm64 埠)和執行在 AMD64-based macOS 上的 iOS 模擬器(ios/amd64 埠)上,Go 1.18 現在需要 iOS 12 或更高版本;對先前版本的支援已停止。

FreeBSD

Go 1.18 是最後一個支援 FreeBSD 11.x 的版本,該版本已達到生命週期結束。Go 1.19 將需要 FreeBSD 12.2+ 或 FreeBSD 13.0+。FreeBSD 13.0+ 將需要設定了 COMPAT_FREEBSD12 選項的核心(這是預設設定)。

工具

模糊測試

Go 1.18 包含了 模糊測試提案 中描述的模糊測試實現。

請參閱 模糊測試登陸頁面 以開始使用。

請注意,模糊測試會消耗大量記憶體,並可能在執行時影響您的機器效能。另請注意,模糊測試引擎在執行時會將擴充套件測試覆蓋率的值寫入 $GOCACHE/fuzz 中的模糊測試快取目錄。目前對模糊測試快取中可以寫入的檔案數量或總位元組數沒有限制,因此它可能會佔用大量儲存空間(可能達到幾個 GB)。

Go 命令

go get

go get 在模組感知模式下不再構建或安裝包。go get 現在專門用於調整 go.mod 中的依賴項。實際上,-d 標誌始終啟用。要在當前模組上下文之外安裝可執行檔案的最新版本,請使用 go install example.com/cmd@latest。任何 版本查詢 都可以代替 latest。這種形式的 go install 是在 Go 1.16 中新增的,因此支援舊版本的專案可能需要提供 go installgo get 的安裝說明。當在模組外部使用時,go get 現在會報告錯誤,因為沒有 go.mod 檔案可供更新。在 GOPATH 模式下(使用 GO111MODULE=off),go get 仍然像以前一樣構建和安裝包。

自動 go.modgo.sum 更新

go mod graphgo mod vendorgo mod verifygo mod why 子命令不再自動更新 go.modgo.sum 檔案。(這些檔案可以使用 go getgo mod tidygo mod download 顯式更新。)

go version

go 命令現在將版本控制資訊嵌入到二進位制檔案中。它包括當前檢出的修訂版、提交時間以及一個標誌,指示是否存在已編輯或未跟蹤的檔案。如果 go 命令是在 Git、Mercurial、Fossil 或 Bazaar 倉庫內的目錄中呼叫的,並且 main 包及其包含的主模組位於同一倉庫中,則會嵌入版本控制資訊。此資訊可以使用 -buildvcs=false 標誌省略。

此外,go 命令還嵌入了有關構建的資訊,包括構建和工具標籤(使用 -tags 設定)、編譯器、彙編器和連結器標誌(如 -gcflags)、cgo 是否啟用,如果啟用,cgo 環境變數(如 CGO_CFLAGS)的值。VCS 和構建資訊都可以與模組資訊一起使用 go version -m fileruntime/debug.ReadBuildInfo(對於當前執行的二進位制檔案)或新的 debug/buildinfo 包讀取。

嵌入式構建資訊的底層資料格式可能會隨 Go 新版本而變化,因此較舊版本的 go 可能無法處理由較新版本 go 生成的構建資訊。要從用 go 1.18 構建的二進位制檔案中讀取版本資訊,請使用 go 1.18+ 中的 go version 命令和 debug/buildinfo 包。

go mod download

如果主模組的 go.mod 檔案指定 go 1.17 或更高版本,則不帶引數的 go mod download 現在僅下載主模組 go.mod 檔案中顯式 所需 模組的原始碼。(在 go 1.17 或更高版本的模組中,該集合已經包含構建主模組中的包和測試所需的所有依賴項。)要同時下載傳遞依賴項的原始碼,請使用 go mod download all

go mod vendor

go mod vendor 子命令現在支援 -o 標誌來設定輸出目錄。(其他 go 命令在使用 -mod=vendor 載入包時仍從模組根目錄的 vendor 目錄讀取,因此此標誌的主要用途是用於需要收集包原始碼的第三方工具。)

go mod tidy

go mod tidy 命令現在會在 go.sum 檔案中保留額外的校驗和,用於驗證 構建列表 中每個匯入的包是否僅由一個模組提供所需的模組原始碼。因為這種情況很少見,而且未能應用會導致構建錯誤,所以此更改 受主模組 go.mod 檔案中的 go 版本限制。

go work

go 命令現在支援“工作區”模式。如果在工作目錄或父目錄中找到 go.work 檔案,或者使用 GOWORK 環境變數指定了檔案,它將使 go 命令進入工作區模式。在工作區模式下,將使用 go.work 檔案來確定用作模組解析根的主模組集,而不是使用通常找到的 go.mod 檔案來指定單個主模組。有關更多資訊,請參閱 go work 文件。

go build -asan

go build 命令和相關命令現在支援 -asan 標誌,該標誌啟用與使用地址清理器編譯的 C(或 C++)程式碼(C 編譯器選項 -fsanitize=address)的互操作。

go test

go 命令現在支援上述新 模糊測試支援 的附加命令列選項

  • go test 支援 -fuzz-fuzztime-fuzzminimizetime 選項。有關這些選項的文件,請參閱 go help testflag
  • go clean 支援 -fuzzcache 選項。有關文件,請參閱 go help clean

//go:build

Go 1.17 引入了 //go:build 行,作為編寫構建約束的一種更具可讀性的方式,而不是 // +build 行。從 Go 1.17 開始,gofmt 會新增 //go:build 行以匹配現有的 +build 行並保持同步,而 go vet 會診斷它們不同步的情況。

由於 Go 1.18 版本的釋出標誌著對 Go 1.16 支援的結束,所有受支援的 Go 版本現在都理解 //go:build 行。在 Go 1.18 中,go fix 現在會刪除在其 go.mod 檔案中宣告 go 1.18 或更高版本的模組中現已過時的 // +build 行。

有關更多資訊,請參閱 go.dev/design/draft-gobuild

Gofmt

gofmt 現在併發讀取和格式化輸入檔案,記憶體限制與 GOMAXPROCS 成比例。在多 CPU 機器上,gofmt 現在應該明顯更快。

Vet

泛型更新

vet 工具已更新以支援泛型程式碼。在大多數情況下,只要在將型別引數替換為其 型別集 中的型別後,它會在等效的非泛型程式碼中報告錯誤,它就會在泛型程式碼中報告錯誤。例如,vet 會報告以下格式錯誤:

func Print[T ~int|~string](t T) {
    fmt.Printf("%d", t)
}

因為它會在 Print[string] 的非泛型等效程式碼中報告格式錯誤。

func PrintString(x string) {
    fmt.Printf("%d", x)
}

現有檢查器的精度改進

cmd/vet 檢查器 copylockprintfsortslicetestinggoroutinetests 都已獲得適度的精度改進,以處理額外的程式碼模式。這可能會導致現有包中報告新的錯誤。例如,printf 檢查器現在會跟蹤透過連線字串常量建立的格式字串。因此 vet 將在以下程式碼中報告錯誤:

  // fmt.Printf formatting directive %d is being passed to Println.
  fmt.Println("%d"+` ≡ x (mod 2)`+"\n", x%2)

執行時

垃圾收集器現在在確定執行頻率時包含非堆垃圾收集器工作源(例如,堆疊掃描)。因此,當這些源很重要時,垃圾收集器開銷更具可預測性。對於大多數應用程式,這些更改可以忽略不計;但是,一些 Go 應用程式現在可能比以前使用更少的記憶體並花費更多時間進行垃圾收集,反之亦然。預期的解決方法是在必要時調整 GOGC

執行時現在更有效地將記憶體返回給作業系統,並且因此進行了更積極的調整。

Go 1.17 通常改進了堆疊跟蹤中引數的格式,但可能會列印暫存器中傳遞的引數的不準確值。Go 1.18 透過在每個可能不準確的值後面列印問號 (?) 來改進這一點。

內建函式 append 在必須分配新的底層陣列時,在決定切片增長多少時使用略有不同的公式。新公式不太容易出現分配行為的突然轉變。

編譯器

Go 1.17 實現 了一種新的方法,在某些作業系統上使用暫存器而不是堆疊傳遞函式引數和結果,用於 64 位 x86 架構。Go 1.18 將支援的平臺擴充套件到包括 64 位 ARM (GOARCH=arm64)、大端和小端 64 位 PowerPC (GOARCH=ppc64ppc64le),以及所有作業系統上的 64 位 x86 架構 (GOARCH=amd64)。在 64 位 ARM 和 64 位 PowerPC 系統上,基準測試顯示典型效能提升 10% 或更多。

如 Go 1.17 釋出說明中 所述,此更改不影響任何安全 Go 程式碼的功能,旨在對大多數彙編程式碼沒有影響。有關更多詳細資訊,請參閱 Go 1.17 釋出說明

編譯器現在可以內聯包含範圍迴圈或帶標籤的 for 迴圈的函式。

新的 -asan 編譯器選項支援新的 go 命令 -asan 選項。

由於編譯器型別檢查器已完全替換以支援泛型,因此某些錯誤訊息現在可能使用與以前不同的措辭。在某些情況下,Go 1.18 之前的錯誤訊息提供了更多詳細資訊或措辭更具幫助性。我們打算在 Go 1.19 中解決這些情況。

由於編譯器中與支援泛型相關的更改,Go 1.18 編譯速度可能比 Go 1.17 編譯速度慢大約 15%。編譯程式碼的執行時間不受影響。我們打算在未來版本中提高編譯器的速度。

連結器

連結器發出的 重定位量大大減少。因此,大多數程式碼庫連結速度更快,連結所需記憶體更少,並生成更小的二進位制檔案。處理 Go 二進位制檔案的工具應使用 Go 1.18 的 debug/gosym 包來透明地處理舊的和新的二進位制檔案。

新的 -asan 連結器選項支援新的 go 命令 -asan 選項。

引導

從原始碼構建 Go 版本時,如果未設定 GOROOT_BOOTSTRAP,則 Go 的早期版本會在 $HOME/go1.4 目錄(Windows 上為 %HOMEDRIVE%%HOMEPATH%\go1.4)中查詢 Go 1.4 或更高版本的引導工具鏈。Go 現在首先查詢 $HOME/go1.17$HOME/sdk/go1.17,然後才回退到 $HOME/go1.4。我們打算讓 Go 1.19 要求 Go 1.17 或更高版本進行引導,此更改應該使過渡更順暢。有關更多詳細資訊,請參閱 go.dev/issue/44505

標準庫

新的 debug/buildinfo

新的 debug/buildinfo 包提供對 go 命令構建的可執行檔案中嵌入的模組版本、版本控制資訊和構建標誌的訪問。相同的資訊也可以透過 runtime/debug.ReadBuildInfo(對於當前執行的二進位制檔案)和命令列上的 go version -m 獲得。

新的 net/netip

新的 net/netip 包定義了一個新的 IP 地址型別 Addr。與現有的 net.IP 型別相比,netip.Addr 型別佔用記憶體更少,是不可變的,並且可比較,因此它支援 == 並可以用作對映鍵。

除了 Addr,該包還定義了 AddrPort(表示 IP 和埠)和 Prefix(表示網路 CIDR 字首)。

該包還定義了幾個函式來建立和檢查這些新型別:AddrFrom4AddrFrom16AddrFromSliceAddrPortFromIPv4UnspecifiedIPv6LinkLocalAllNodesIPv6UnspecifiedMustParseAddrMustParseAddrPortMustParsePrefixParseAddrParseAddrPortParsePrefixPrefixFrom

net 包包含新的方法,這些方法與現有方法並行,但返回 netip.AddrPort 而不是更重量級的 net.IP*net.UDPAddr 型別:Resolver.LookupNetIPUDPConn.ReadFromUDPAddrPortUDPConn.ReadMsgUDPAddrPortUDPConn.WriteToUDPAddrPortUDPConn.WriteMsgUDPAddrPort。新的 UDPConn 方法支援無分配 I/O。

net 包現在還包括在現有 TCPAddr/UDPAddr 型別和 netip.AddrPort 之間進行轉換的函式和方法:TCPAddrFromAddrPortUDPAddrFromAddrPortTCPAddr.AddrPort客戶端預設停用 TLS 1.0 和 1.1

如果未設定 Config.MinVersion,則對於客戶端連線,它現在預設為 TLS 1.2。任何安全更新的伺服器都應支援 TLS 1.2,並且自 2020 年以來瀏覽器已要求使用它。透過將 Config.MinVersion 設定為 VersionTLS10,仍然支援 TLS 1.0 和 1.1。伺服器端預設值保持不變為 TLS 1.0。

可以透過設定 GODEBUG=tls10default=1 環境變數暫時將預設值恢復為 TLS 1.0。此選項將在 Go 1.19 中刪除。

拒絕 SHA-1 證書

crypto/x509 現在將拒絕使用 SHA-1 雜湊函式簽名的證書。這不適用於自簽名根證書。自 2017 年以來,針對 SHA-1 的實際攻擊 已得到證實,並且自 2015 年以來,公開受信任的證書頒發機構未頒發 SHA-1 證書。

可以透過設定 GODEBUG=x509sha1=1 環境變數暫時恢復此功能。此選項將在未來版本中刪除。

對庫的微小更改

與往常一樣,庫中有各種微小的更改和更新,這些都是在遵守 Go 1 相容性承諾的前提下進行的。

bufio

新的 Writer.AvailableBuffer 方法返回一個空緩衝區,該緩衝區可能具有非空容量,用於 append-like API。追加後,可以將緩衝區提供給後續的 Write 呼叫,並可能避免任何複製。

在對具有 nil 緩衝區的物件呼叫時,Reader.ResetWriter.Reset 方法現在使用預設緩衝區大小。

bytes

新的 Cut 函式圍繞分隔符切割 []byte。它可以替換和簡化許多常見的 IndexIndexByteIndexRuneSplitN 用法。

TrimTrimLeftTrimRight 現在無分配,尤其對於小的 ASCII 剪下集,速度提高了 10 倍。

Title 函式現已棄用。它不處理 Unicode 標點符號和特定語言的字母大寫規則,並已被 golang.org/x/text/cases 包取代。

crypto/elliptic

P224P384P521 曲線實現現在都由 addchainfiat-crypto 專案生成的程式碼支援,後者基於經過形式化驗證的算術運算模型。它們現在使用更安全的完整公式和內部 API。P-224 和 P-384 現在大約快四倍。所有特定的曲線實現現在都是恆定時間的。

對無效曲線點(即 IsOnCurve 方法返回 false,且從未由 Unmarshal 或對有效點操作的 Curve 方法返回的點)進行操作一直是未定義的行為,可能導致金鑰恢復攻擊,並且新後端現在不支援。如果向 P224P384P521 方法提供無效點,該方法現在將返回一個隨機點。此行為在未來版本中可能會更改為顯式 panic。

crypto/tls

新的 Conn.NetConn 方法允許訪問底層的 net.Conn

crypto/x509

當使用 nil VerifyOpts.Roots 呼叫 Certificate.Verify 或使用從 SystemCertPool 返回的根池時,它現在在 macOS 和 iOS 上使用平臺 API 驗證證書有效性。

SystemCertPool 現在可在 Windows 上使用。

在 Windows、macOS 和 iOS 上,當 SystemCertPool 返回的 CertPool 添加了額外的證書時,Certificate.Verify 將進行兩次驗證:一次使用平臺驗證器 API 和系統根,另一次使用 Go 驗證器和額外的根。平臺驗證器 API 返回的鏈將優先。

CertPool.Subjects 已棄用。在 Windows、macOS 和 iOS 上,由 SystemCertPool 返回的 CertPool 將返回一個不包含 Subjects 返回的切片中的系統根的池,因為靜態列表無法適當表示平臺策略,並且可能根本無法從平臺 API 獲取。

Go 1.19 中可能會刪除對使用依賴於 MD5 雜湊(MD5WithRSA)的簽名演算法簽署證書的支援。

debug/dwarf

StructFieldBasicType 結構體現在都有一個 DataBitOffset 欄位,該欄位儲存 DW_AT_data_bit_offset 屬性的值(如果存在)。

debug/elf

已新增 R_PPC64_RELATIVE 常量。

debug/plan9obj

如果檔案沒有符號節,File.Symbols 方法現在返回新的匯出錯誤值 ErrNoSymbols

embed

go:embed 指令現在可以以 all: 開頭,以包含名稱以點或下劃線開頭的檔案。

go/ast

根據提案 向 go/ast 和 go/token 新增支援引數化函式和型別的功能,對 go/ast 包進行了以下新增:

  • FuncTypeTypeSpec 節點有一個新的欄位 TypeParams 用於儲存型別引數(如果有)。
  • 新的表示式節點 IndexListExpr 表示具有多個索引的索引表示式,用於具有多個顯式型別引數的函式和型別例項化。

go/constant

新的 Kind.String 方法返回接收器型別的可讀名稱。

go/token

根據提案 向 go/ast 和 go/token 新增支援引數化函式和型別的功能,新的常量 TILDE 表示 ~ 標記。

go/types

新的 Config.GoVersion 欄位設定接受的 Go 語言版本。

根據提案 向 go/types 新增支援型別引數的功能,對 go/types 包進行了以下新增:

謂詞 AssignableToConvertibleToImplementsIdenticalIdenticalIgnoreTagsAssertableTo 現在也適用於是或包含泛型介面的引數,即只能在 Go 程式碼中用作型別約束的介面。請注意,對於未例項化的泛型型別引數,AssignableToConvertibleToImplementsAssertableTo 的行為是未定義的,並且如果第一個引數是泛型介面,則 AssertableTo 是未定義的。

html/template

range 管道中,新的 {{break}} 命令將提前結束迴圈,新的 {{continue}} 命令將立即開始下一次迴圈迭代。

and 函式不再總是評估所有引數;它在第一個評估為 false 的引數之後停止評估引數。類似地,or 函式現在在第一個評估為 true 的引數之後停止評估引數。如果任何引數是函式呼叫,這會產生影響。

image/draw

當引數不是最常見的影像型別時,DrawDrawMask 回退實現(用於這種情況)現在更快,如果這些引數實現了 Go 1.17 中新增的可選 draw.RGBA64Imageimage.RGBA64Image 介面。

net

net.Error.Temporary 已棄用。

net/http

在 WebAssembly 目標上,Transport 中的 DialDialContextDialTLSDialTLSContext 方法欄位現在將被正確使用,如果指定,用於發出 HTTP 請求。

新的 Cookie.Valid 方法報告 cookie 是否有效。

新的 MaxBytesHandler 函式建立一個 Handler,該 Handler 將其 ResponseWriterRequest.Body 包裝在 MaxBytesReader 中。

在查詢包含非 ASCII 字元的域名時,Unicode 到 ASCII 的轉換現在根據 Unicode IDNA 相容性處理 標準 (UTS #46) 中定義的非過渡處理進行。四個不同的 rune 的解釋發生了變化:ß、ς、零寬度連線符 U+200D 和零寬度非連線符 U+200C。非過渡處理與大多數應用程式和 Web 瀏覽器保持一致。

os/user

當 cgo 不可用時,User.GroupIds 現在使用 Go 原生實現。

reflect

新的 Value.SetIterKeyValue.SetIterValue 方法使用對映迭代器作為源設定 Value。它們等效於 Value.Set(iter.Key())Value.Set(iter.Value()),但分配更少。

新的 Value.UnsafePointer 方法以 unsafe.Pointer 的形式返回 Value 的值。這允許呼叫者從 Value.UnsafeAddrValue.Pointer 遷移,以消除在呼叫點執行 uintptr 到 unsafe.Pointer 轉換的需要(如 unsafe.Pointer 規則所要求)。

新的 MapIter.Reset 方法更改其接收器以迭代不同的對映。使用 MapIter.Reset 允許對許多對映進行無分配迭代。

已向 Value 添加了許多方法(Value.CanIntValue.CanUintValue.CanFloatValue.CanComplex)以測試轉換是否安全。

已新增 Value.FieldByIndexErr 以避免在透過 nil 指標步進到嵌入式結構體時 Value.FieldByIndex 中發生的 panic。

reflect.Ptrreflect.PtrTo 已分別重新命名為 reflect.Pointerreflect.PointerTo,以與 reflect 包的其餘部分保持一致。舊名稱將繼續有效,但在未來的 Go 版本中將被棄用。

regexp

regexp 現在將 UTF-8 字串的每個無效位元組視為 U+FFFD

runtime/debug

BuildInfo 結構體有兩個新欄位,包含有關二進位制檔案如何構建的額外資訊:

  • GoVersion 儲存用於構建二進位制檔案的 Go 版本。
  • Settings 是一個 BuildSettings 結構體切片,儲存描述構建的鍵/值對。

runtime/pprof

CPU 效能分析器現在在 Linux 上使用每執行緒計時器。這增加了效能分析可觀察到的最大 CPU 使用率,並減少了某些形式的偏差。

strconv

strconv.Unquote 現在拒絕 Unicode 代理對。

strings

新的 Cut 函式圍繞分隔符切割 string。它可以替換和簡化許多常見的 IndexIndexByteIndexRuneSplitN 用法。

新的 Clone 函式複製輸入 string,而返回的克隆 string 不引用輸入字串的記憶體。

TrimTrimLeftTrimRight 現在無分配,尤其對於小的 ASCII 剪下集,速度提高了 10 倍。

Title 函式現已棄用。它不處理 Unicode 標點符號和特定語言的字母大寫規則,並已被 golang.org/x/text/cases 包取代。

sync

新的方法 Mutex.TryLockRWMutex.TryLockRWMutex.TryRLock 將在當前未持有時獲取鎖。

syscall

為 Windows 引入了新函式 SyscallN,允許呼叫任意數量的引數。因此,SyscallSyscall6Syscall9Syscall12Syscall15Syscall18 已棄用,轉而使用 SyscallN

FreeBSD 現在支援 SysProcAttr.Pdeathsig

syscall/js

Wrapper 介面已被移除。

testing

-run-bench 引數中 / 的優先順序已提高。A/B|C/D 以前被視為 A/(B|C)/D,現在被視為 (A/B)|(C/D)

如果 -run 選項沒有選擇任何測試,則忽略 -count 選項。這可能會在測試每次執行時更改子測試集的情況下,改變現有測試的行為(儘管這種情況不太可能發生)。

新的 testing.F 型別由上述新 模糊測試支援 使用。測試現在還支援命令列選項 -test.fuzz-test.fuzztime-test.fuzzminimizetime

text/template

range 管道中,新的 {{break}} 命令將提前結束迴圈,新的 {{continue}} 命令將立即開始下一次迴圈迭代。

and 函式不再總是評估所有引數;它在第一個評估為 false 的引數之後停止評估引數。類似地,or 函式現在在第一個評估為 true 的引數之後停止評估引數。如果任何引數是函式呼叫,這會產生影響。

text/template/parse

該包透過新常量 NodeBreak 和新型別 BreakNode 支援新的 text/templatehtml/template {{break}} 命令,並透過新常量 NodeContinue 和新型別 ContinueNode 支援新的 {{continue}} 命令。

unicode/utf8

新的 AppendRune 函式將 rune 的 UTF-8 編碼附加到 []byte