Go 1.22 釋出說明

Go 1.22 簡介

最新的 Go 版本 1.22 在 Go 1.21 釋出六個月後到來。其大部分更改都在工具鏈、執行時和庫的實現中。一如既往,此版本保持了 Go 1 的相容性承諾。我們預計幾乎所有 Go 程式都將像以前一樣繼續編譯和執行。

語言變化

Go 1.22 對“for”迴圈做了兩處更改。

  • 以前,“for”迴圈宣告的變數只建立一次,並由每次迭代更新。在 Go 1.22 中,迴圈的每次迭代都會建立新變數,以避免意外的共享錯誤。提案中描述的過渡支援工具與 Go 1.21 中的工作方式相同。

  • “For”迴圈現在可以迭代整數。例如:示例

    package main
    
    import "fmt"
    
    func main() {
      for i := range 10 {
        fmt.Println(10 - i)
      }
      fmt.Println("go1.22 has lift-off!")
    }
    

    有關詳細資訊,請參閱規範。

Go 1.22 包含我們正在考慮用於未來 Go 版本的語言更改的預覽:基於函式的迭代器。使用 GOEXPERIMENT=rangefunc 構建將啟用此功能。

工具

Go 命令

工作區中的命令現在可以使用包含工作區依賴項的 vendor 目錄。該目錄由 go work vendor 建立,並在 -mod 標誌設定為 vendor 時由構建命令使用,當工作區 vendor 目錄存在時,這是預設設定。

請注意,工作區的 vendor 目錄內容與單個模組的內容不同:如果工作區根目錄中的目錄也包含工作區中的某個模組,則其 vendor 目錄可以包含工作區或模組的依賴項,但不能同時包含兩者。

在舊版 GOPATH 模式下(即,使用 GO111MODULE=off),模組外部不再支援 go get。其他構建命令,如 go buildgo test,將無限期地繼續用於舊版 GOPATH 程式。

go mod init 不再嘗試從其他 vendoring 工具(例如 Gopkg.lock)的配置檔案中匯入模組要求。

go test -cover 現在會為沒有自己的測試檔案的已覆蓋包列印覆蓋率摘要。在 Go 1.22 之前,對此類包執行 go test -cover 會報告

? mymod/mypack [no test files]

現在,使用 Go 1.22,包中的函式被視為未覆蓋

mymod/mypack coverage: 0.0% of statements

請注意,如果一個包根本不包含任何可執行程式碼,我們無法報告有意義的覆蓋率百分比;對於此類包,go 工具將繼續報告沒有測試檔案。

如果將使用外部(C)連結器但未啟用 cgo,則呼叫連結器的 go build 命令現在會出錯。(Go 執行時需要 cgo 支援以確保它與 C 連結器新增的任何額外庫相容。)

Trace

trace 工具的 Web UI 已作為支援新跟蹤器的工作的一部分進行了輕微重新整理,解決了多個問題並改進了各種子頁面的可讀性。Web UI 現在支援線上程導向檢視中探索跟蹤。跟蹤檢視器現在還顯示所有系統呼叫的完整持續時間。
這些改進僅適用於檢視由 Go 1.22 或更高版本構建的程式生成的跟蹤。未來版本將把其中一些改進帶到由舊版本 Go 生成的跟蹤。

Vet

對迴圈變數的引用

vet 工具的行為已更改以匹配 Go 1.22 中迴圈變數的新語義(見上文)。在分析需要 Go 1.22 或更高版本的檔案時(由於其 go.mod 檔案或每檔案構建約束),vet 不再報告函式字面量中對迴圈變數的引用,這些引用可能會超出迴圈的迭代週期。在 Go 1.22 中,每次迭代都會為迴圈變數重新建立新變數,因此此類引用不再面臨在變數被迴圈更新後使用它的風險。

append 後缺少值的新警告

vet 工具現在報告對 append 的呼叫,這些呼叫沒有傳遞要附加到切片的值,例如 slice = append(slice)。這樣的語句沒有效果,經驗表明這幾乎總是一個錯誤。

defer time.Since 的新警告

vet 工具現在報告 defer 語句中對 time.Since(t) 的非延遲呼叫。這等效於在 defer 語句之前呼叫 time.Now().Sub(t),而不是在延遲函式呼叫時。在幾乎所有情況下,正確的程式碼都需要延遲 time.Since 呼叫。例如

t := time.Now()
defer log.Println(time.Since(t)) // non-deferred call to time.Since
tmp := time.Since(t); defer log.Println(tmp) // equivalent to the previous defer

defer func() {
  log.Println(time.Since(t)) // a correctly deferred call to time.Since
}()

log/slog 呼叫中鍵值對不匹配的新警告

vet 工具現在報告結構化日誌包 log/slog 中接受交替鍵值對的函式和方法呼叫中的無效引數。它報告鍵位置的引數既不是 string 也不是 slog.Attr 的呼叫,以及最終鍵缺少其值的呼叫。

執行時

執行時現在將基於垃圾回收的元資料儲存在靠近每個堆物件的位置,將 Go 程式的 CPU 效能(延遲或吞吐量)提高 1-3%。此更改還透過消除冗餘元資料的重複,將大多數 Go 程式的記憶體開銷減少約 1%。一些程式可能會看到較小的改進,因為此更改調整了記憶體分配器的尺寸類別邊界,因此某些物件可能會向上移動一個尺寸類別。

此更改的一個結果是,某些以前始終對齊到 16 位元組(或更高)邊界的物件地址現在將只對齊到 8 位元組邊界。某些使用需要記憶體地址對齊超過 8 位元組的彙編指令並依賴記憶體分配器以前的對齊行為的程式可能會中斷,但我們預計此類程式很少見。此類程式可以使用 GOEXPERIMENT=noallocheaders 構建,以恢復舊的元資料佈局並恢復以前的對齊行為,但包所有者應更新其彙編程式碼以避免對齊假設,因為此解決方法將在未來版本中刪除。

windows/amd64 埠上,連結或載入使用 -buildmode=c-archive-buildmode=c-shared 構建的 Go 庫的程式現在可以使用 SetUnhandledExceptionFilter Win32 函式來捕獲 Go 執行時未處理的異常。請注意,這在 windows/386 埠上已經支援。

編譯器

配置檔案引導最佳化 (PGO) 構建現在可以比以前虛擬化更高比例的呼叫。現在,代表性 Go 程式集中的大多數程式在啟用 PGO 後執行時效能提高了 2% 到 14%。

編譯器現在交錯進行反虛擬化和內聯,因此介面方法呼叫得到了更好的最佳化。

Go 1.22 還包括編譯器內聯階段的增強實現的預覽,該階段使用啟發式方法來提高被認為是“重要”的呼叫站點(例如,在迴圈中)的內聯性,並阻止被認為是“不重要”的呼叫站點(例如,在 panic 路徑上)的內聯。使用 GOEXPERIMENT=newinliner 構建將啟用新的呼叫站點啟發式;有關更多資訊和提供反饋,請參閱問題 #61502

連結器

連結器的 -s-w 標誌現在在所有平臺上表現得更一致。-w 標誌禁止生成 DWARF 除錯資訊。-s 標誌禁止生成符號表。-s 標誌也暗示 -w 標誌,可以用 -w=0 否定。也就是說,-s -w=0 將生成一個帶有 DWARF 除錯資訊但沒有符號表的二進位制檔案。

在 ELF 平臺上,-B 連結器標誌現在接受一種特殊形式:使用 -B gobuildid,連結器將生成一個源自 Go 構建 ID 的 GNU 構建 ID(ELF NT_GNU_BUILD_ID 註釋)。

在 Windows 上,當使用 -linkmode=internal 進行構建時,連結器現在透過將 .pdata.xdata 部分複製到最終二進位制檔案中來保留 C 物件檔案中的 SEH 資訊。這有助於使用 WinDbg 等本機工具除錯和分析二進位制檔案。請注意,直到現在,C 函式的 SEH 異常處理程式一直未被遵守,因此此更改可能會導致某些程式的行為不同。-linkmode=external 不受此更改的影響,因為外部連結器已經保留了 SEH 資訊。

引導

Go 1.20 釋出說明中所述,Go 1.22 現在需要 Go 1.20 或更高版本的最終點發布版本才能進行引導。我們預計 Go 1.24 將需要 Go 1.22 或更高版本的最終點發布版本才能進行引導。

標準庫

新的 math/rand/v2 包

Go 1.22 包含標準庫中的第一個“v2”包,math/rand/v2。與 math/rand 相比的更改在提案 #61716 中有詳細說明。最重要的更改是

  • math/rand 中已棄用的 Read 方法並未在 math/rand/v2 中沿用。(它在 math/rand 中仍然可用。)絕大多數 Read 呼叫應改用 crypto/randRead。否則,可以使用 Uint64 方法構造自定義的 Read
  • 頂級函式訪問的全域性生成器是無條件隨機種子化的。由於 API 不保證固定的結果序列,因此現在可以實現諸如每執行緒隨機生成器狀態之類的最佳化。
  • Source 介面現在有一個單一的 Uint64 方法;沒有 Source64 介面。
  • 許多方法現在使用更快的演算法,這些演算法在 math/rand 中無法採用,因為它們改變了輸出流。
  • math/rand 中的 IntnInt31Int31nInt63Int64n 頂級函式和方法在 math/rand/v2 中拼寫更符合習慣用法:IntNInt32Int32NInt64Int64N。還有新的頂級函式和方法 Uint32Uint32NUint64Uint64NUintN
  • 新的泛型函式 N 類似於 Int64NUint64N,但適用於任何整數型別。例如,從 0 到 5 分鐘的隨機持續時間是 rand.N(5*time.Minute)
  • math/randSource 提供的 Mitchell & Reeds LFSR 生成器已被兩個更現代的偽隨機生成器源取代:ChaCha8PCG。ChaCha8 是一種新的、密碼學上強大的隨機數生成器,效率與 PCG 大致相似。ChaCha8 是 math/rand/v2 中頂級函式使用的演算法。從 Go 1.22 開始,math/rand 的頂級函式(未明確種子化時)和 Go 執行時也使用 ChaCha8 進行隨機性。

我們計劃在未來的版本中(很可能是 Go 1.23)包含一個 API 遷移工具。

新的 go/version 包

新的 go/version 包實現了用於驗證和比較 Go 版本字串的函式。

增強的路由模式

標準庫中的 HTTP 路由現在更具表達性。net/http.ServeMux 使用的模式已增強以接受方法和萬用字元。

使用方法(例如 "POST /items/create")註冊處理程式會將處理程式的呼叫限制為具有給定方法的請求。帶有方法的模式優先於匹配但沒有方法的模式。作為特例,使用 "GET" 註冊處理程式也會將其註冊為 "HEAD"

模式中的萬用字元(例如 /items/{id})匹配 URL 路徑的段。可以透過呼叫 Request.PathValue 方法訪問實際的段值。以“…”結尾的萬用字元(例如 /files/{path...})必須出現在模式的末尾並匹配所有剩餘的段。

以“/”結尾的模式始終匹配所有以其為字首的路徑。要匹配包括尾隨斜槓在內的精確模式,請以 {$} 結尾,如 /exact/match/{$}

如果兩個模式在它們匹配的請求中重疊,則更具體的模式優先。如果兩者都不更具體,則模式衝突。此規則概括了原始優先順序規則並保持了模式註冊順序無關緊要的屬性。

此更改以小範圍破壞了向後相容性,有些是顯而易見的——帶有“{”和“}”的模式行為不同——有些則不那麼明顯——對轉義路徑的處理得到了改進。此更改由名為 httpmuxgo121GODEBUG 欄位控制。設定 httpmuxgo121=1 以恢復舊行為。

對庫的微小更改

一如既往,庫中進行了各種小的更改和更新,始終牢記 Go 1 的相容性承諾。還有各種未在此處列出的效能改進。

archive/tar

新方法 Writer.AddFSfs.FS 中的所有檔案新增到歸檔。

archive/zip

新方法 Writer.AddFSfs.FS 中的所有檔案新增到歸檔。

bufio

SplitFunc 返回帶有 nil 令牌的 ErrFinalToken 時,Scanner 現在會立即停止。以前,它會在停止之前報告一個最終的空令牌,這通常不是期望的行為。如果呼叫者確實想報告一個最終的空令牌,可以透過返回 []byte{} 而不是 nil 來實現。

cmp

新函式 Or 返回一系列值中第一個非零值。

crypto/tls

ConnectionState.ExportKeyingMaterial 現在將返回一個錯誤,除非正在使用 TLS 1.3,或者伺服器和客戶端都支援 extended_master_secret 擴充套件。crypto/tls 自 Go 1.20 以來一直支援此擴充套件。這可以透過 tlsunsafeekm=1 GODEBUG 設定停用。

預設情況下,如果未透過 config.MinimumVersion 指定,crypto/tls 伺服器提供的最低版本現在是 TLS 1.2,這與 crypto/tls 客戶端的行為相匹配。此更改可以透過 tls10server=1 GODEBUG 設定恢復。

預設情況下,在 TLS 1.3 之前的握手期間,客戶端和伺服器都不再提供不支援 ECDHE 的密碼套件。此更改可以透過 tlsrsakex=1 GODEBUG 設定恢復。

crypto/x509

新的 CertPool.AddCertWithConstraint 方法可用於向根證書新增自定義約束,以便在鏈構建期間應用。

在 Android 上,根證書現在將從 /data/misc/keychain/certs-added/system/etc/security/cacerts 載入。

一種新型別 OID 支援 ASN.1 物件識別符號,其單個元件大於 31 位。Certificate 結構中添加了一個使用此型別的新欄位 Policies,並且現在在解析期間填充。任何無法使用 asn1.ObjectIdentifier 表示的 OID 將出現在 Policies 中,但不會出現在舊的 PolicyIdentifiers 欄位中。呼叫 CreateCertificate 時,Policies 欄位將被忽略,策略將從 PolicyIdentifiers 欄位中獲取。使用 x509usepolicies=1 GODEBUG 設定會反轉此行為,從 Policies 欄位填充證書策略,並忽略 PolicyIdentifiers 欄位。我們可能會在 Go 1.23 中更改 x509usepolicies 的預設值,使 Policies 成為封送的預設欄位。

database/sql

新的 Null[T] 型別提供了一種掃描任何列型別的可空列的方法。

debug/elf

定義了常量 R_MIPS_PC32 以用於 MIPS64 系統。

定義了額外的 R_LARCH_* 常量以用於 LoongArch 系統。

編碼

encoding/base32encoding/base64encoding/hex 包中,Encoding 型別的每個新方法 AppendEncodeAppendDecode 透過處理位元組切片緩衝區管理,簡化了位元組切片的編碼和解碼。

現在,如果 padding 引數是除 NoPadding 以外的負值,則 base32.Encoding.WithPaddingbase64.Encoding.WithPadding 方法會發生 panic。

encoding/json

封送和編碼功能現在將 '\b''\f' 字元轉義為 \b\f,而不是 \u0008\u000c

go/ast

以下與句法識別符號解析相關的宣告現在已棄用Ident.ObjObjectScopeFile.ScopeFile.UnresolvedImporterPackageNewPackage。通常,在沒有型別資訊的情況下無法準確解析識別符號。例如,考慮 T{K: ""} 中的識別符號 K:如果 T 是對映型別,它可能是區域性變數的名稱;如果 T 是結構型別,它可能是欄位的名稱。新程式應使用 go/types 包來解析識別符號;有關詳細資訊,請參閱ObjectInfo.UsesInfo.Defs

新的 ast.Unparen 函式從表示式中移除任何外部的括號

go/types

新的 Alias 型別表示類型別名。以前,類型別名沒有明確表示,因此對類型別名的引用等同於拼寫出別名型別,並且別名的名稱會丟失。新的表示保留了中間的 Alias。這可以改進錯誤報告(可以報告類型別名的名稱),並允許更好地處理涉及類型別名的迴圈型別宣告。在未來的版本中,Alias 型別還將攜帶型別引數資訊。新函式 Unalias 返回 Alias 型別(或任何其他Type)所表示的實際型別。

由於 Alias 型別可能會破壞現有型別開關,這些開關不知道如何檢查它們,此功能由名為 gotypesaliasGODEBUG 欄位控制。當 gotypesalias=0 時,一切都像以前一樣,並且永遠不會建立 Alias 型別。當 gotypesalias=1 時,會建立 Alias 型別,客戶端必須預期它們。預設值為 gotypesalias=0。在未來的版本中,預設值將更改為 gotypesalias=1強烈建議 go/types 的客戶端儘快調整其程式碼以使用 gotypesalias=1,以便及早消除問題。

Info 結構現在匯出了 FileVersions 對映,該對映提供每個檔案的 Go 版本資訊。

新的輔助方法 PkgNameOf 返回給定匯入宣告的本地包名稱。

SizesFor 的編譯器引數為 "gc" 時,SizesFor 的實現已調整為計算與編譯器相同的型別大小。型別檢查器使用的預設 Sizes 實現現在是 types.SizesFor("gc", "amd64")

表示函式體的詞法環境塊(Scope)的起始位置(Pos)已更改:以前它從函式體的左花括號開始,但現在從函式的 func 標記開始。

html/template

JavaScript 模板字面量現在可以包含 Go 模板操作,解析包含此類模板的模板將不再返回 ErrJSTemplate。同樣,GODEBUG 設定 jstmpllitinterp 也不再有任何效果。

io

新的 SectionReader.Outer 方法返回傳遞給 NewSectionReaderReaderAt、偏移量和大小。

日誌/slog

新的 SetLogLoggerLevel 函式控制 sloglog 包之間橋接的級別。它設定了對頂級 slog 日誌函式呼叫的最小級別,並設定了透過 slog 進行的 log.Logger 呼叫的級別。

math/big

新方法 Rat.FloatPrec 計算將有理數精確表示為浮點數所需的十進位制小數位數,以及是否首先可能進行精確的十進位制表示。

net

io.CopyTCPConn 複製到 UnixConn 時,如果可能,它現在將使用 Linux 的 splice(2) 系統呼叫,方法是使用新方法 TCPConn.WriteTo

Go DNS 解析器(在使用“-tags=netgo”構建時使用)現在會在進行 DNS 查詢之前,在 Windows 主機檔案(位於 %SystemRoot%\System32\drivers\etc\hosts)中搜索匹配的名稱。

net/http

新函式 ServeFileFSFileServerFSNewFileTransportFS 是現有 ServeFileFileServerNewFileTransport 的版本,操作於 fs.FS

HTTP 伺服器和客戶端現在拒絕包含無效空 Content-Length 標頭的請求和響應。透過設定 GODEBUG 欄位 httplaxcontentlength=1 可以恢復之前的行為。

新方法 Request.PathValue 從請求返回路徑萬用字元值,新方法 Request.SetPathValue 設定請求上的路徑萬用字元值。

net/http/cgi

當執行 CGI 程序時,PATH_INFO 變數現在總是設定為空字串或以 / 字元開頭的值,這符合 RFC 3875 的要求。以前,某些 Handler.Root 和請求 URL 的組合可能會違反此要求。

net/netip

新的 AddrPort.Compare 方法比較兩個 AddrPort

os

在 Windows 上,Stat 函式現在會遵循所有連結到系統中另一個命名實體的重解析點。以前它只遵循 IO_REPARSE_TAG_SYMLINKIO_REPARSE_TAG_MOUNT_POINT 重解析點。

在 Windows 上,將 O_SYNC 傳遞給 OpenFile 現在會導致寫入操作直接寫入磁碟,這等同於 Unix 平臺上的 O_SYNC

在 Windows 上,ReadDirFile.ReadDirFile.Readdirnames 函式現在分批讀取目錄條目,以減少系統呼叫次數,從而將效能提高高達 30%。

io.CopyFile 複製到 net.UnixConn 時,如果可能,它現在將使用 Linux 的 sendfile(2) 系統呼叫,使用新方法 File.WriteTo

os/exec

在 Windows 上,LookPath 現在會忽略 %PATH% 中的空條目,如果找不到可執行副檔名來解析一個原本明確的名稱,則返回 ErrNotFound(而不是 ErrNotExist)。

在 Windows 上,如果可執行檔案的路徑已經是絕對路徑且具有可執行副檔名,則 CommandCmd.Start 不再呼叫 LookPath。此外,Cmd.Start 不再將解析後的副檔名寫回 Path 欄位,因此現在可以安全地在呼叫 Start 的同時併發呼叫 String 方法。

reflect

Value.IsZero 方法現在將對浮點數或複數負零返回 true,並且如果空白欄位(名為 _ 的欄位)以某種方式具有非零值,則將對結構體值返回 true。這些更改使 IsZero 與使用語言 == 運算子將值與零進行比較保持一致。

PtrTo 函式已棄用,取而代之的是 PointerTo

新函式 TypeFor 返回表示型別引數 T 的 Type。以前,要獲取型別的 reflect.Type 值,必須使用 reflect.TypeOf((*T)(nil)).Elem()。現在可以寫成 reflect.TypeFor[T]()

runtime/metrics

四個新的直方圖指標 /sched/pauses/stopping/gc:seconds/sched/pauses/stopping/other:seconds/sched/pauses/total/gc:seconds/sched/pauses/total/other:seconds 提供了關於停頓世界暫停的額外詳細資訊。“stopping”指標報告從決定停止世界到所有 goroutine 停止所花費的時間。“total”指標報告從決定停止世界到再次啟動所花費的時間。

/gc/pauses:seconds 指標已棄用,因為它等同於新的 /sched/pauses/total/gc:seconds 指標。

/sync/mutex/wait/total:seconds 現在除了 sync.Mutexsync.RWMutex 之外,還包括執行時內部鎖的爭用。

runtime/pprof

互斥鎖配置檔案現在透過阻塞在互斥鎖上的 goroutine 數量來縮放爭用。這提供了互斥鎖在 Go 程式中成為瓶頸的程度的更準確表示。例如,如果 100 個 goroutine 在互斥鎖上阻塞 10 毫秒,則互斥鎖配置檔案現在將記錄 1 秒的延遲,而不是 10 毫秒的延遲。

互斥鎖配置檔案現在還包括執行時內部鎖的爭用,除了 sync.Mutexsync.RWMutex 之外。執行時內部鎖的爭用始終在 runtime._LostContendedRuntimeLock 報告。未來版本將在此類情況下新增完整的堆疊跟蹤。

Darwin 平臺上的 CPU 配置檔案現在包含程序的記憶體對映,從而可以在 pprof 工具中啟用反彙編檢視。

runtime/trace

此版本中,執行跟蹤器已完全 overhauled,解決了幾個長期存在的問題,併為執行跟蹤的新用例鋪平了道路。

執行跟蹤現在在大多數平臺(Windows 除外)上使用作業系統時鐘,因此可以將其與低階元件生成的跟蹤相關聯。執行跟蹤不再依賴平臺時鐘的可靠性來生成正確的跟蹤。執行跟蹤現在在執行時定期分割槽,因此可以以流式方式處理。執行跟蹤現在包含所有系統呼叫的完整持續時間。執行跟蹤現在包含 goroutine 執行的作業系統執行緒的資訊。啟動和停止執行跟蹤的延遲影響已大大減少。執行跟蹤現在可以在垃圾回收標記階段開始或結束。

為了讓 Go 開發者能夠利用這些改進,可以在 golang.org/x/exp/trace 獲取一個實驗性跟蹤讀取包。請注意,目前此包僅適用於由 Go 1.22 或更高版本構建的程式生成的跟蹤。請嘗試使用該包並在相應的提案問題上提供反饋。

如果您遇到新的執行跟蹤器實現問題,可以透過使用 GOEXPERIMENT=noexectracer2 構建 Go 程式來切換回舊實現。如果您這樣做,請提交問題,否則此選項將在未來版本中刪除。

切片

新函式 Concat 連線多個切片。

縮小切片大小的函式(DeleteDeleteFuncCompactCompactFuncReplace)現在會將新長度和舊長度之間的元素清零。

如果引數 i 超出範圍,Insert 現在總是 panic。以前,在這種情況下如果沒有要插入的元素,它不會 panic。

syscall

syscall 包自 Go 1.4 以來一直處於凍結狀態,並在 Go 1.11 中被標記為已棄用,導致許多編輯器在使用該包時發出警告。然而,某些未棄用的功能需要使用 syscall 包,例如 os/exec.Cmd.SysProcAttr 欄位。為了避免此類程式碼上不必要的抱怨,syscall 包不再被標記為已棄用。該包仍凍結了大多數新功能,並且新程式碼仍鼓勵在可能的情況下使用 golang.org/x/sys/unixgolang.org/x/sys/windows

在 Linux 上,新的 SysProcAttr.PidFD 欄位允許在透過 StartProcessos/exec 啟動子程序時獲取 PID FD。

在 Windows 上,將 O_SYNC 傳遞給 Open 現在會導致寫入操作直接寫入磁碟,這等同於 Unix 平臺上的 O_SYNC

testing/slogtest

新的 Run 函式使用子測試來執行測試用例,提供更細粒度的控制。

移植

Darwin

在 64 位 x86 架構的 macOS 上(darwin/amd64 埠),Go 工具鏈現在預設生成位置無關可執行檔案 (PIE)。可以透過指定 -buildmode=exe 構建標誌來生成非 PIE 二進位制檔案。在 64 位 ARM 架構的 macOS 上(darwin/arm64 埠),Go 工具鏈已經預設生成 PIE。

Go 1.22 是最後一個可以在 macOS 10.15 Catalina 上執行的版本。Go 1.23 將需要 macOS 11 Big Sur 或更高版本。

ARM

GOARM 環境變數現在允許您選擇使用軟體浮點還是硬體浮點。以前,有效的 GOARM 值為 567。現在這些相同的值可以可選地後跟 ,softfloat,hardfloat 來選擇浮點實現。

此新選項預設版本 5softfloat,版本 67hardfloat

Loong64

loong64 埠現在支援使用暫存器傳遞函式引數和結果。

linux/loong64 埠現在支援地址清理器、記憶體清理器、新式連結器重定位和 plugin 構建模式。

OpenBSD

Go 1.22 增加了對大端 64 位 PowerPC 上的 OpenBSD 的實驗性埠 (openbsd/ppc64)。