Go 1.21 發行說明
Go 1.21 簡介
最新的 Go 發行版 1.21 於 Go 1.20 的六個月後推出。絕大部分變更在於工具鏈、執行時期和函式庫的實作。與以往相同,此發行版維持了 Go 1 相容性的承諾;事實上,Go 1.21 加強了這項承諾。我們預期幾乎所有的 Go 程式都可以像以前一樣繼續編譯和執行。
Go 1.21 引進了發行版編號的一個小改變。過往,我們使用 Go 1.N 來同時代表整體的 Go 語言版本和發行系列,以及該系列中的第一個發行版。從 Go 1.21 開始,第一個發行版現在是 Go 1.N.0。今天我們同時發行了 Go 1.21 語言及其初始實作,也就是 Go 1.21.0 發行版。這些說明指的是「Go 1.21」;像 go
version
這樣的工具會回報「go1.21.0
」(直至您升級到 Go 1.21.1)。有關新版本編號的詳細資料,請參閱「Go 工具鏈」文件中的「Go 版本」。
語言變更
Go 1.21 在語言中新增了三項內建函數。
-
新函數
min
與max
會計算數個特定引數的最小值(或最大值,若為max
)。請參閱語言規範,以取得 詳細資料。 -
新函數
clear
會從地圖中刪除所有元素,或將區塊中的所有元素歸零。請參閱語言規範,以取得 詳細資料。
套件初始化順序現在有更精確的說明。新演算法如下:
- 依據匯入路徑排序所有套件。
- 重複執行以下動作,直至套件清單為空
- 尋找清單中第一個所有匯入都已初始化的套件。
- 初始化該套件,並將其從清單中移除。
這可能會改變仰賴特定初始化順序的程式行為,但該順序並未在明確的匯入中表達出來。此類程式的行為並未在過去版本的規範中明確定義。新規則提供了明確的定義。
已進行多項改進,以提高型別推論的功效與精準度。
- (部分)實體化泛型的函數現在可以用身為其它泛型函數(部分實體化或非實體化)的引數來呼叫。編譯器將嘗試推論被呼叫方的遺漏型別引數(如同之前一樣),而且針對每個身為未完全實體化泛型函數的引數,其遺漏型別引數(新功能)。常見的使用案例包括對處理容器(例如 slices.IndexFunc)的泛型函數進行呼叫,其中一個函數引數也可能是泛型的,且已呼叫函數及其引數的型別引數會從容器型別推論出來。更一般來說,如果從指派中或作為結果值傳回,泛型函數現在可在沒有明確實體化時使用,只要型別引數可從指派中推論出來即可。
- 當將一個值指派給介面時,型別推論現在也會考量方法:方法簽章中使用的型別參數的型別引數可能會從相符方法的相對應參數型別中推論出來。
- 類似地,由於一個型別引數必須實作其相對應約束的所有方法,型別引數與約束的方法會進行比對,這可能會導致推論出其他型別引數。
- 如果將不同類型的多個未打過型別的常數引數(例如未打過型別的 int,以及未打過型別的浮點常數)傳遞給 دارای相同(未另行指定的)型別參數類型的參數,現在型別推論會使用與未打過型別常數運算元的相同方式來決定型別,而不是出現錯誤。這個變更讓未打過型別常數引數推論的型別與常數運算式的型別一致。
- 現已精確地推斷指派中對應型態的型態:元件型態(例如區段元素,或函式簽章中的參數型態)必須(在適當的型態引數下)一致,才能配對,否則將推論失敗。此變更產生了更精確的錯誤訊息:在過去,型態推論可能不正確,並導致無效的指派,現在如果兩個型態無法配對,編譯器會回報推論錯誤。
更一般而言,語言規範中 型態推論 的描述已得到澄清。總之,所有這些變更讓型態推論功能更強大,且推論失敗的情況不再令人感到意外。
Go 1.21 包含了我們正在考慮在未來版本的 Go 中進行的語言變更預覽:將 for 迴圈變數改為每次迭代一個,而非每個迴圈一個,以避免意外的共用錯誤。有關如何嘗試該語言變更的詳細資訊,請參閱 LoopvarExperiment wiki 頁面。
Go 1.21 現已定義,如果 goroutine 正在恐慌,且 recover 是由遞延函式直接呼叫的,recover 的傳回值保證不會為 nil。為確保這一點,使用 nil 介面值(或未指定型別的 nil)呼叫 panic 會導致執行時期 *runtime.PanicNilError
型態的恐慌。
為了支援為舊版本 Go 編寫的程式,可以透過設定 GODEBUG=panicnil=1
來重新啟用 nil 恐慌。如果編譯程式的 main 套件在宣告 go
1.20
或更早版本的模組中,此設定會自動啟用。
工具
Go 1.21 新增了對 Go toolchain 中的向後相容性和向前相容性的改善支援。
為了改善向後相容性,Go 1.21 正式化了 Go 使用 GODEBUG 環境變數來控制根據 相容性政策 不會中斷的變更的預設行為,但可能導致現有程式中斷。(例如,依賴錯誤行為的程式可能會在錯誤修復時中斷,但錯誤修正不會被視為中斷變更。)當 Go 必須進行這類行為變更時,它現在會根據工作區 `go.work` 檔案(或主模組的 `go.mod` 檔案)中的 `go` 列,選擇舊或新行為。升級到新的 Go toolchain,但將 `go` 列設定為其原始(舊)的 Go 版本,會保留舊工具鏈的行為。有了這種相容性支援,最新的 Go toolchain 應該是始終最好的、最安全的舊版 Go 實作。有關詳細資訊,請參閱「Go、向後相容性,以及 GODEBUG」。
為提升向前相容性,Go 1.21 現將 go.work
或 go.mod
檔案中的 go
列視為嚴格的最低需求:go
1.21.0
表示工作區或模組無法與 Go 1.20 或 Go 1.21rc1 搭配使用。如此一來,仰賴後續 Go 版本修正的專案就能確保不與較早版本搭配使用。此外,它也改善了使用較新 Go 功能的專案的錯誤回報:當問題在於需要使用較新版本的 Go 時,問題將會明確回報,而非嘗試建置程式碼並列印未解析的匯入或語法錯誤。
為讓這些新的嚴格版本需求更容易管理,go
指令現不僅能呼叫其自身版本中所加載的工具鏈,也能呼叫 PATH 中的其他 Go 工具鏈版本,或依需求下載。如果 go.mod
或 go.work
go
列針對較新版本的 Go 宣告最低需求,go
指令將會自動找出並執行該版本。新的 toolchain
指令會設定建議使用的最低工具鏈,可能較嚴格的 go
最低版本更新。詳情請參考「Go 工具鏈」
Go 指令
-pgo
建置標記現預設為 -pgo=auto
,且現已移除在指令列中指定單一主要套件的限制。如果在主要套件的目錄中存在名為 default.pgo
的檔案,go
指令會使用它來啟用建置對應程式時所做的剖析導向最佳化。
使用時,-C
dir
標記現在必須是指令列中的第一個標記。
新的 go
test
選項 -fullpath
會在測試日誌訊息中列印完整路徑名稱,而非僅列印基礎名稱。
go
test
-c
標記現在支援為多個套件撰寫測試二進位檔案,每個套件撰寫至 pkg.test
,其中 pkg
為套件名稱。如果有多個測試套件已編譯,且具有相同的套件名稱,則會出錯。
go
test
-o
標記現在接受目錄參數,如此一來,測試二進位檔案會寫至該目錄,而非目前的目錄。
當在啟動 cgo 的情況下使用外部 (C) 連結器時,現會將 runtime/cgo
套件作為額外的相依項提供給 Go 連結器,以確保 Go 執行時期與 C 連結器新增的任何額外函式庫相容。
Cgo
在匯入「import "C"」的檔案中,Go 工具鏈現在會針對嘗試對 C 類型宣告 Go 方法的行為正確回報錯誤。
執行時期
列印非常深的堆疊時,執行時期現在會先列印前 50 個(最內層)的框架,接著是最後 50 個(最外層)的框架,而不再只列印前 100 個框架。這使得觀看高度遞迴堆疊的起點變得更容易,特別對於除錯堆疊溢位很有幫助。
在支援透明巨型頁面的 Linux 平台上,Go 執行時期現在能夠更明確地管理堆疊的哪些部分可以使用巨型頁面作為後盾。這可以更有效地利用記憶體:小型堆疊應該可減少佔用的記憶體(在病態個案中最多可減少 50%),而大型堆疊應該可以減少堆疊密集區塊的破碎巨型頁面,進而改善 CPU 使用率和延遲,最高可達 1%。此項變更的後果是,執行時期不再嘗試變通某些有問題的 Linux 設定,這可能會導致較高的記憶體開銷。建議的修復方法是根據 GC 指南調整作業系統的巨型頁面設定。不過,還有其他變通方法。請參閱 關於 max_ptes_none
的部分。
由於執行時期內部垃圾收集調整,應用程式可能看到應用程式尾部延遲減少達 40%,記憶體使用量則略有減少。有些應用程式也可能看到吞吐量略微下降。記憶體使用量的減少應與吞吐量的損失成正比,因此可以透過稍微增加 GOGC
和/或 GOMEMLIMIT
,找回前一個版本的吞吐量/記憶體權衡(對延遲幾乎沒有改變)。
在 C 中建立的執行緒上從 C 呼叫 Go 時,需要進行一些設定以準備執行 Go。在 Unix 平台上,這個設定現在會保留在同一個執行緒中的多個呼叫之間。這可大幅減少後續從 C 呼叫 Go 的開銷,從每個呼叫大約 1-3 微秒減少到每個呼叫大約 100-200 奈秒。
編譯器
已在 Go 1.20 中新增為預覽版的概觀指導最佳化(PGO),現在準備供一般用途。PGO 可對生產工作負載概觀標示為重要的程式碼進行額外的最佳化。如 Go 指令部分 中所述,如果二進位檔包含主要套件目錄中的 default.pgo
概觀,則會預設啟用 PGO。效能改善會依應用程式的行為而異,在具代表性的 Go 程式組中,大多數程式啟用 PGO 後可看到改善 2% 到 7%。請參閱 PGO 使用者指南 以取得詳細文件。
PGO 建置現在可以解除某些介面方法呼叫的虛擬化,增加對最常見呼叫者的具體呼叫。這可以進一步最佳化,例如內聯呼叫者。
Go 1.21 可將建置速度提高達 6%,主要是因為使用 PGO 建置編譯器本身。
組譯器
在 amd64 上,無框 nosplit 巢狀函數不再自動標示為 NOFRAME
。與此相反,如果需要,必須明確地指定 NOFRAME
屬性,而這是支援幀指標的其他架構上的行為。藉此,執行時期現在維護堆疊轉換的幀指標。
在 amd64 上動態連結時,檢查錯誤使用 R15
的驗證器已獲得改進。
連結器
在 windows/amd64 上,連結器(透過編譯器的協助)現在預設發出 SEH 展開資料,這改善了 Go 應用程式與 Windows 除錯器及其他工具的整合。
在 Go 1.21 中,連結器(透過編譯器的協助)現在有能力刪除非活態(未參考)的全球 map 變數,如果變數初始化程式中的條目數量足夠大,以及如果初始化器表達式沒有副作用。
標準函式庫
新的 log/slog 套件
新的 log/slog 套件提供具有層級結構的記錄功能。結構式的記錄發出關鍵字對,以針對大量的記錄資料進行快速、精確的處理。此套件支援與熱門的記錄分析工具和服務進行整合。
新的 testing/slogtest 套件
新的 testing/slogtest 套件可以協助驗證 slog.Handler 實作。
新的 slices 套件
新的 slices 套件針對片斷提供許多常用的操作,使用通用的函數,此類函數可用於任何元素類型片斷。
新的 maps 套件
新的 maps 套件針對集合提供許多常用的操作,使用通用的函數,此類函數可用於任何鍵或元素類型集合。
新的 cmp 套件
新的 cmp 套件定義類型約束 Ordered
和兩個新的通用函數 Less
與 Compare
,此類函數對於 已排序類型很有用。
函式庫的次要變更
一如往常,對於函式庫進行了許多次要的變更和更新,並考慮了 Go 1 相容性的承諾。也有許多效能改善未在此列出。
archive/tar
現在由 Header.FileInfo
所回傳的 io/fs.FileInfo
介面的實作實作呼叫 io/fs.FormatFileInfo
的 String
方法。
archive/zip
由 FileHeader.FileInfo
傳回的 io/fs.FileInfo
介面實作現在實作一個會呼叫 io/fs.FormatFileInfo
的 String
方法。
由 Reader.Open
傳回的 io/fs.File
的 io/fs.ReadDirFile.ReadDir
方法傳回的 io/fs.DirEntry
介面實作現在實作一個會呼叫 io/fs.FormatDirEntry
的 String
方法。
位元組
Buffer
型別有兩個新的方法:Available
和 AvailableBuffer
。這些方法可以和 Write
方法一起使用,以便直接加在 Buffer
。
context
新的 WithoutCancel
函式傳回一個 context 的拷貝,當原始 context 被取消時不會被取消。
新的 WithDeadlineCause
和 WithTimeoutCause
函式提供了在截止時間或計時器到期時設定 context 取消原因的方法。原因可以透過 Cause
函式取得。
新的 AfterFunc
函式註冊一個函式,當 context 被取消後執行。
最佳化表示呼叫 Background
和 TODO
並將它們轉換為共用型別,結果可以視為相等。在之前的版本中,它們總是不同。比較 Context
值以查看相等性,從來沒有很明確的定義,因此這不被視為不向後相容的變更。
crypto/ecdsa
PublicKey.Equal
和 PrivateKey.Equal
現在會以常數時間執行。
crypto/elliptic
所有 Curve
方法已被棄用,GenerateKey
、Marshal
和 Unmarshal
也是如此。對於 ECDH 操作,應該改用新的 crypto/ecdh
套件。對於低階操作,請使用第三方模組,例如 filippo.io/nistec。
crypto/rand
現在 crypto/rand
封裝使用 NetBSD 10.0 及後續版本的 getrandom
系統呼叫。
crypto/rsa
對於私人 RSA 作業(解密和簽章),其效能現在優於 Go 1.19,適用於 GOARCH=amd64
和 GOARCH=arm64
。其在 Go 1.20 中已回歸。
由於新增了私人欄位到 PrecomputedValues
,即使是反序列化(例如從 JSON)先前預先運算的私人金鑰,也必須呼叫 PrivateKey.Precompute
以獲得最佳效能。
PublicKey.Equal
和 PrivateKey.Equal
現在會以恆定時間執行。
GenerateMultiPrimeKey
函數和 PrecomputedValues.CRTValues
欄位已棄用。在呼叫 PrivateKey.Precompute
時,仍會填入 PrecomputedValues.CRTValues
,但解密作業中不會使用這些值。
crypto/sha256
在 GOARCH=amd64
可用時,SHA-224 和 SHA-256 作業現在會使用原生指令,這將效能提升了 3-4 倍。
crypto/tls
除了檢查到期時間外,伺服器現在會略過驗證用戶端憑證(包括不執行 Config.VerifyPeerCertificate
)用於已重新啟動的連線。這會讓工作階段票證在使用用戶端憑證時變大。用戶端在重新啟動時已會略過驗證,但現在即使設定了 Config.InsecureSkipVerify
,也會檢查到期時間。
現在應用程式可以控制工作階段票證的內容。
- 新的
SessionState
類型會描述一個可重新啟動的工作階段。 SessionState.Bytes
方法和ParseSessionState
函數會序列化和反序列化一個SessionState
。Config.WrapSession
和Config.UnwrapSession
掛鉤會在伺服器端將一個SessionState
轉換成一個票證,反之亦然。Config.EncryptTicket
和Config.DecryptTicket
方法提供了WrapSession
和UnwrapSession
的預設實作。ClientSessionState.ResumptionState
方法和NewResumptionState
函數可供ClientSessionCache
執行實作儲存和重新啟動客戶端端的會話。
為了降低會話通行證可用於跨連線的追蹤機制的可能性,伺服器現已在每次重新啟動時發布新的通行證(如果通行證受到支援且未停用),而且通行證不再帶有用於加密它們的金鑰識別碼。如果傳遞大量的金鑰到 Conn.SetSessionTicketKeys
,這可能會導致明顯的效能成本。
客戶端和伺服器現已執行延展主密碼擴充功能 (RFC 7627)。ConnectionState.TLSUnique
的已棄用狀態已還原,並已設定為支援延展主密碼的重新啟動連線。
新的 QUICConn
類型提供對 QUIC 執行實作的支援,包括 0-RTT 支援。請注意,這本身並非 QUIC 的執行實作,0-RTT 仍未受 TLS 支援。
新的 VersionName
函數會傳回 TLS 版本號碼的名稱。
伺服器在客戶端驗證失敗時發出的 TLS 警示代碼已獲得改善。以前,這些失敗總是會導致「錯誤憑證」警示。現在,某些失敗會導致更適當的警示代碼,如 RFC 5246 和 RFC 8446 所定義的
- 對於 TLS 1.3 連線,如果伺服器已設定為需要使用 RequireAnyClientCert 或 RequireAndVerifyClientCert 來進行客戶端驗證,且客戶端未提供任何憑證,伺服器現在會傳回「需要憑證」警示。
- 如果客戶端提供未由伺服器上設定的受信任憑證簽章機關所簽署的憑證,伺服器會傳回「未知憑證簽章機關」警示。
- 如果客戶端提供已過期或尚未有效的憑證,伺服器會傳回「過期憑證」警示。
- 在與客戶端驗證失敗相關的所有其他情況下,伺服器仍傳回「錯誤憑證」。
crypto/x509
RevocationList.RevokedCertificates
已被棄用,並改用新的 RevokedCertificateEntries
欄位,後者是 RevocationListEntry
的區塊。RevocationListEntry
包含 pkix.RevokedCertificate
中的所有欄位,以及撤銷原因代碼。
名稱約束現已針對非葉狀憑證正確地執行,並未針對表達這些約束的憑證執行。
debug/elf
新的 File.DynValue
方法可讓您擷取特定動態標記所列出的數字值。
現在將 DT_FLAGS_1
動態標籤中允許的常數旗標定義為類型 DynFlag1
。這些標籤的名稱以 DF_1
開頭。
現在套件定義常數 COMPRESS_ZSTD
。
現在套件定義常數 R_PPC64_REL24_P9NOTOC
。
debug/pe
嘗試使用 Section.Data
或 Section.Open
傳回的讀取器,從包含未初始化資料的區段讀取,現在會傳回錯誤。
embed
現在 FS.Open
傳回的 io/fs.File
具有實作 io.ReaderAt
的 ReadAt
方法。
呼叫 FS.Open.Stat
會傳回現在實作呼叫 io/fs.FormatFileInfo
的 String
方法的類型。
encoding/binary
新的 NativeEndian
變數可用於使用目前電腦的原生 endianness,在位元組區段和整數之間轉換。
errors
新的 ErrUnsupported
錯誤提供一個標準化的方式,用來表示無法執行請求的操作,因為它不受支援。例如,當使用不支援硬連結的檔案系統時,呼叫 os.Link
。
flag
新的 BoolFunc
函數和 FlagSet.BoolFunc
方法定義一個不需要參數的旗標,而且當使用該旗標時,它會呼叫一個函數。這類似於用於布林旗標的 Func
。
如果已在名稱相同的旗標上呼叫 Set
,旗標定義(經由 Bool
、BoolVar
、Int
、IntVar
等)會發生恐慌。此變更旨在偵測在什麼情況下,初始化順序的變更 會導致旗標操作發生在與預期不同的順序中。在許多情況下,此問題的解決方法是引入明確的套件依賴關係,以在任何 Set
操作之前,正確對定義排序。
go/ast
新的 IsGenerated
謂詞會回報檔案語法樹是否包含 特殊註解,它通常表示該檔案是由工具產生的。
新的 File.GoVersion
欄位會記錄任何 //go:build
或 // +build
指令所需的最小 Go 版本。
go/build
套件現在會分析檔案標頭中 (在「package」宣告之前) 的建構指令 (以「//go:」開頭的註解)。這些指令可在新的 Package
欄位中使用:Directives
、TestDirectives
和 XTestDirectives
。
go/build/constraint
新的 GoVersion
函式會傳回建構表達式暗示的最低 Go 版本。
go/token
新的 File.Lines
方法會傳回檔案的行數表,其格式與「File.SetLines」接受的格式相同。
go/types
新的 Package.GoVersion
方法會傳回用來檢查套件的 Go 語言版本。
hash/maphash
hash/maphash
套件現在有純 Go 實作,可用建構標籤「purego」來選擇。
html/template
當動作出現在 JavaScript 的範本字串中時,新的錯誤 ErrJSTemplate
將會傳回。先前會傳回一個未匯出的錯誤。
io/fs
新的 FormatFileInfo
函式會傳回格式化的 FileInfo
版本。新的 FormatDirEntry
函式會傳回格式化的 DirEntry
版本。ReadDir
傳回的 DirEntry
的實作現在會實作一個 String
方法,用來呼叫 FormatDirEntry
,傳遞給 WalkDirFunc
的 DirEntry
值也是如此。
math/big
新的 Int.Float64
方法會傳回多重精確度的整數最接近的浮點值,以及發生捨入的指示。
net
在 Linux 上,當核心支援時,net 套件現在可以使用多路徑 TCP。此功能並非預設啟用。若要在客戶端使用多路徑 TCP,請在呼叫 Dialer.Dial
或 Dialer.DialContext
方法之前呼叫 Dialer.SetMultipathTCP
方法。若要在伺服器上使用多路徑 TCP,請在呼叫 ListenConfig.Listen
方法之前呼叫 ListenConfig.SetMultipathTCP
方法。將網路指定為像往常一樣的 "tcp"
、「tcp4」或 "tcp6"
。如果核心或遠端主機不支援多路徑 TCP,連線將會靜默地回復到 TCP。若要測試特定連線是否使用多路徑 TCP,請使用 TCPConn.MultipathTCP
方法。
在未來的 Go 版本中,我們可能會在支援的多重路徑 TCP 系統上預設啟用多路徑 TCP。
net/http
新的 ResponseController.EnableFullDuplex
方法允許伺服器處理常式在寫入回應時同時從 HTTP/1 請求主體進行讀取。一般來說,HTTP/1 伺服器會在開始寫入回應前自動使用任何剩餘請求主體,以避免在嘗試在讀取回應前寫入完整請求時發生客戶端鎖死。EnableFullDuplex
方法已停用此行為。
當伺服器以 HTTP 回應回應 HTTPS 請求時,Client
和 Transport
會傳回新的 ErrSchemeMismatch
錯誤。
net/http 套件現在支援 errors.ErrUnsupported
,表達式 errors.Is(http.ErrNotSupported, errors.ErrUnsupported)
會傳回 true。
os
程式現在可以傳遞空值 time.Time
給 Chtimes
函式,以不變動存取時間或修改時間。
在 Windows 上,File.Chdir
方法現在會將目前目錄變更為檔案,而非總是傳回錯誤。
在 Unix 系統上,如果將非封鎖描述子傳遞給 NewFile
,呼叫 File.Fd
方法現在會傳回非封鎖描述子。以前描述子已轉換為封鎖模式。
在 Windows 上,對不存在檔案呼叫 Truncate
用於建立一個空檔案。現在會傳回一個錯誤,指出檔案不存在。
在 Windows 上,呼叫 TempDir
現在在可用時使用 GetTempPath2W,而非 GetTempPathW。新行為是一項安全性強化措施,能防止以 SYSTEM 身分執行的處理所建立的暫存檔案被非 SYSTEM 處理存取。
在 Windows 上,os 套件現在支援處理檔案名稱,儲存為 UTF-16,無法表示為有效的 UTF-8。
在 Windows 上,Lstat
現在會解析以路徑分隔符結尾的路徑的符號連結,符合其在 POSIX 平臺上的行為。
由 ReadDir
函式和 File.ReadDir
方法傳回的 io/fs.DirEntry
介面的實作,現在實作一個呼叫 io/fs.FormatDirEntry
的 String
方法。
由 DirFS
函式傳回的 io/fs.FS
介面的實作,現在實作 io/fs.ReadFileFS
和 io/fs.ReadDirFS
介面。
path/filepath
傳遞給 WalkDir
函式引數的 io/fs.DirEntry
介面實作現在執行一個呼叫 io/fs.FormatDirEntry
的 String
方法。
reflect
在 Go 1.21 中, ValueOf
不再強制其引數在堆疊上配置,允許 Value
的內容在堆疊上配置。大多數針對 Value
的操作也允許底層值在堆疊上配置。
新的 Value
方法 Value.Clear
會清除映射的內容或使切片的內容歸零。這與 新增至語言 中的新內建 clear
相應。
SliceHeader
和 StringHeader
型別現在已遭棄用。在新程式碼中,優先使用 unsafe.Slice
, unsafe.SliceData
, unsafe.String
或 unsafe.StringData
。
regexp
Regexp
現在定義了 MarshalText
和 UnmarshalText
方法。這些實作了 encoding.TextMarshaler
和 encoding.TextUnmarshaler
,並將由 encoding/json 等套件使用。
runtime
由 Go 程式產生之文字堆疊追蹤(例如那些在發生故障、呼叫 runtime.Stack
或以 debug=2
蒐集 goroutine 概況時產生)現在包含在堆疊追蹤中建立每個 goroutine 之 goroutine 的 ID。
發生故障的 Go 應用程式現在可選擇加入 Windows 錯誤回報 (WER) 服務,方式是在發生故障之前設定環境變數 GOTRACEBACK=wer
或呼叫 debug.SetTraceback("wer")
。除了啟用 WER 以外,執行時期將以與 GOTRACEBACK=crash
時相同的模式運作。在非 Windows 系統上,GOTRACEBACK=wer
會被忽略。
仔細檢查 cgo 指標傳遞規則的 偵錯選項 GODEBUG=cgocheck=2
不再可用。現在使用 GOEXPERIMENT=cgocheck2
,將其設定為實驗。特別是,表示必須在建置時間而不是啟動時間選擇此模式。
GODEBUG=cgocheck=1
仍可用(而且仍然是預設)。
已新增一個新的型別 Pinner
至 runtime 套件。Pinner
可能用於「固定」Go 記憶體,使其能更自由地供非 Go 程式碼使用。例如,現在允許將參照已固定 Go 記憶體的 Go 值傳遞給 C 程式碼。先前,此類巢狀參照無法依 cgo 指標傳遞規則 而傳遞。如需更多詳細資料,請參閱 文件。
runtime/metrics
一些以前內部的 GC 指標(例如目前的堆疊大小)現在已推出。GOGC
和 GOMEMLIMIT
也以指標的形式推出。
runtime/trace
現在在 amd64 和 arm64 上收集追蹤資訊所產生的 CPU 成本大幅降低,與先前的版本相比,改進幅度高達 10 倍。
追蹤資訊現在包含明確的中斷執行緒事件,說明 Go 執行階段中斷執行緒的所有原因,而不再僅限於垃圾回收。
sync
新的 OnceFunc
、OnceValue
和 OnceValues
函式整合了 Once 的常見用法,以在首次使用時延遲初始化一個值。
syscall
在 Windows 上,Fchdir
函式現在會將目前的目錄變更為其參數,而不是永遠傳回錯誤。
在 FreeBSD 上,SysProcAttr
有新的欄位 Jail
,可用於將新建立的程序放置在監獄化環境中。
在 Windows 上,syscall 套件現在支援處理檔案名稱(儲存為 UTF-16)無法表示為有效的 UTF-8 格式。現在,UTF16ToString
和 UTF16FromString
函式會在 UTF-16 資料和 WTF-8 字串之間進行轉換。這具有向後相容性,因為 WTF-8 是先前的版本所使用的 UTF-8 格式的超集。
多項錯誤值與新的 errors.ErrUnsupported
相符,因此 errors.Is(err, errors.ErrUnsupported)
會傳回 true。
ENOSYS
ENOTSUP
EOPNOTSUPP
EPLAN9
(僅限 Plan 9)ERROR_CALL_NOT_IMPLEMENTED
(僅限 Windows)ERROR_NOT_SUPPORTED
(僅限 Windows)EWINDOWS
(僅限 Windows)
testing
新的 -test.fullpath
選項會在測試記錄訊息中列印完整的路徑名稱,而不僅僅是基礎名稱。
新的 Testing
函式會回報程式是否為 go
test
建立的測試。
testing/fstest
呼叫 Open.Stat
會傳回一種現在實作呼叫 io/fs.FormatFileInfo
的 String
方法的類型。
unicode
已將 unicode
套件及其在整個系統中的相關支援升級到 Unicode 15.0.0。
Portions
Darwin
正如在 Go 1.20 發行說明中 宣告 的,Go 1.21 需要 macOS 10.15 Catalina 或更新版本;不再支援前一個版本。
Windows
正如在 Go 1.20 發行說明中 宣告 的,Go 1.21 至少需要 Windows 10 或 Windows Server 2016;不再支援前一個版本。
WebAssembly
新的 go:wasmimport
指令現在可以在 Go 程式碼中使用,用以從 WebAssembly 主機匯入函式。
Go 排程器現在可以和 JavaScript 事件迴圈進行更有效率的互動,特別是在經常會在非同步事件中遭到封鎖的應用程式中。
WebAssembly 系統介面
Go 1.21 加入了一個到 WebAssembly 系統介面 (WASI) 的實驗性埠,其中包含 Preview 1(GOOS=wasip1
、GOARCH=wasm
)。
由於加入了新的 GOOS
值「wasip1
」,除非正在使用該 GOOS
值,否則命名為 *_wasip1.go
的 Go 檔案現在會遭到 Go 工具忽略。如果您有符合該樣式的現有檔名,您需要將其重新命名。
ppc64/ppc64le
在 Linux 上,GOPPC64=power10
現在會產生 PC 相對指令、加前綴指令和其他的新的 Power10 指令。在 AIX 上,GOPPC64=power10
會產生 Power10 指令,但不會產生 PC 相對指令。
對於建置適用於 GOPPC64=power10
GOOS=linux
GOARCH=ppc64le
的位置獨立二進位檔案時,使用者可以在大部分情況下預期二進位檔案大小減少,在某些情況下可以減少 3.5%。位置獨立二進位檔案會使用下列 -buildmode
值為 ppc64le 建置:c-archive
、c-shared
、shared
、pie
、plugin
。
loong64
linux/loong64
埠現在支援 -buildmode=c-archive
、-buildmode=c-shared
和 -buildmode=pie
。