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
,這些函式現在提供建構和解構切片和字串值而不依賴其精確表示式的完整功能。
規格現已定義結構值一次比較一個欄位,按照欄位在結構類型定義中出現的順序考慮欄位,並在第一個不匹配時停止。這個規格以前可能被讀成需要在第一個不匹配之後比較所有欄位。類似地,規格現已定義陣列值一次比較一個元素,依據遞增的 index 順序。在兩個情況下,差異在於是否特定比較必須誘發 panic。現有的程式不變:新的規格說明描述了執行項始終執行的動作。
可比較類型(例如一般介面)現在可以滿足 comparable
約束,即使類型引數不完全可比較(比較在執行時會誘發 panic)。這使得可以使用不完全可比較類型引數(例如介面類型或包含介面類型的複合類型)實例化受限於 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 為 FreeBSD 在 RISC-V (GOOS=freebsd
、GOARCH=riscv64
) 上新增實驗支援。
工具
Go 命令
目錄 $GOROOT/pkg
不再儲存標準程式庫的預先編譯套件封存:go
install
不再寫入它們,go
build
不再檢查它們,而 Go distribution 不再傳送它們。取而代之的是,標準程式庫中的套件會根據需要建立,並快取在建置快取中,就像 GOROOT
之外的套件一樣。這個變更減小了 Go distribution 的大小,並避免使用 cgo 的套件發生 C toolchain skew。
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
go
命令現在預設在系統中沒有 C 工具鏈的情況下停用 cgo
。更具體地說,當 CGO_ENABLED
環境變數是未設定的,CC
環境變數是未設定的,而且在路徑中找不到預設 C 編譯器(通常是 clang
或 gcc
)時,CGO_ENABLED
預設為 0
。一如往常,您可以透過明確設定 CGO_ENABLED
來覆寫預設值。
預設變更最重要的影響在於,當 Go 安裝在沒有 C 編譯器的系統上時,它現在將使用純 Go 編譯來建立標準函式庫中使用 cgo 的套件,而不是使用預先散發的套件封存(如 上述所述,已移除預先散發的套件封存)或嘗試使用 cgo 而失敗。這使得 Go 能夠在某些極小化容器環境中以及在 macOS 上運作良好,自 Go 1.16 起,macOS 已針對基於 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
工具現在會回報在子測試函式本體中呼叫 T.Parallel()
之後的迴圈變數之指標。這些指標可能會從不同的反覆運算(通常會導致跳過測試案例)或因為未同步的同時存取而產生無效的狀態中觀察變數值。
這個工具也會在更多地方偵測到指標錯誤。以前它只會考量迴圈本體的最後一個陳述,但現在它會遞迴檢查 if、switch 和 select 陳述中的最後一個陳述。
對不正確時間格式的新診斷
vet 工具現在會回報使用 Time.Format
和 time.Parse
採用 2006-02-01(yyyy-dd-mm)時間格式。此格式並未出現在常見的日期標準中,但常在嘗試使用 ISO 8601 日期格式(yyyy-mm-dd)時誤用。
執行時期
重新整理了垃圾收集器的部分內部資料結構,使其同時更省空間且更省 CPU。此變更縮減了記憶體開銷,並將整體 CPU 效能提升了最高 2%。
在某些情況下,垃圾收集器在協助執行常式的表現變得比較少變化。
Go 1.20 新增一個 runtime/coverage
套件,其中包含 API,可從不透過 os.Exit()
終止的長時間執行或伺服器程式中,在執行時期寫入程式碼覆蓋率資料。
編譯器
Go 1.20 新增對輪廓引導最佳化 (PGO) 的預覽支援。PGO 讓工具組能根據執行時期輪廓資訊執行特定於應用程式和工作負載的最佳化。目前,編譯器支援 pprof CPU 輪廓,可透過一般方式(例如 runtime/pprof
或 net/http/pprof
套件)收集。如前述 上方 所提,若要啟用 PGO,請透過傳遞 pprof 輪廓檔案的 路徑至 -pgo
旗標來執行 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
目錄中搜尋 Go 1.4 或更新版本的起始工具鏈(%HOMEDRIVE%%HOMEPATH%\go1.4
在 Windows 上)。在預期 Go 1.20 的起始程式需要 Go 1.17 之前,Go 1.18 和 Go 1.19 會先搜尋 $HOME/go1.17
或 $HOME/sdk/go1.17
,然後最後再使用 $HOME/go1.4
。Go 1.20 確實需要 Go 1.17 版本才能進行起始設定,但我們了解應該採用起始工具鏈的最新小版本,因此需要 Go 1.17.13。在使用 $HOME/go1.4
之前(支援硬編碼路徑 $HOME/go1.4
但已安裝較新 Go 工具鏈的系統),Go 1.20 會先搜尋 $HOME/go1.17.13
$HOME/sdk/go1.17.13
。在未來,我們計畫每年將起始工具鏈往前推進一次,特別是,我們預計 Go 1.22 會需要 Go 1.20 的最終小版本才能進行起始設定。
標準程式庫
新的 crypto/ecdh 套件
Go 1.20 新增一個 crypto/ecdh
套件,來明確支援 NIST 曲線和 Curve25519 的橢圓曲線 Diffie-Hellman 金鑰交換。
程式應該針對 ECDH 使用 crypto/ecdh
,而非 crypto/elliptic
中的較低階層功能,以及第三方模組用於更進階的用例。
封裝多重錯誤
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 改寫掛鉤
httputil.ReverseProxy
轉發 proxy 包含一個新的 Rewrite
掛鉤函式,取代以前的 Director
掛鉤。
Rewrite
掛鉤會接受 ProxyRequest
參數,其中包括 proxy 接收到的進程請求和它將傳送的出站請求。這允許 Rewrite
掛鉤避免惡意進程請求會導致掛鉤新增的標頭在轉發之前被移除的特定案例(與只針對出站請求執行的 Director
掛鉤不同)。請參閱 議題 #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
函式提供一個使用指定錯誤取消 context 的方式。可以透過呼叫新的 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
指示。它們現在也支援透過設定新的 Options.Context
欄位所指示的 Ed25519ctx 和 Ed25519ph 與 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
將兩個位元組切片進行 XOR。
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
區段讀取資料現在會傳回錯誤。
新增 R_LARCH_*
常數供與 LoongArch 系統搭配使用。
新增 R_PPC64_*
常數供與 PPC64 ELFv2 重定位搭配使用。
已修正 R_PPC64_SECTOFF_LO_DS
的常数値,從 61 更正為 62。
debug/gosym
由於 Go 符號命名慣例 變更,處理 Go 二進位檔的工具應使用 Go 1.20 的 debug/gosym
套件透明處理舊的和新的二進位檔。
debug/pe
IMAGE_FILE_MACHINE_RISCV*
常數現新增,可搭配 RISC-V 系統使用。
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
關鍵字的位置。
新的 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
新錯誤 SkipAll
會立即終止 WalkDir
,但成功終止。
math/big
math/big
套件的廣泛範圍和依賴輸入的時機,使其不適合執行密碼編譯。標準函式庫的密碼編譯套件不再呼叫攻擊者控制輸入的非 trivial Int 方法。未來,math/big 中的 bug 是否會被視為安全性漏洞,將取決於其對標準函式庫更廣泛的影響。
math/rand
math/rand
套件現在會自動使用隨機值更新全域亂數產生器 (由頂層函式使用,例如 Float64
和 Int
),而頂層 Seed
函式已棄用。需要可複製亂數序列的程式最好分配自己的亂數來源,使用 rand.New(rand.NewSource(種子))
。
需要早先一致全域更新行為的程式可在其環境中設定 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
記錄內容(如果存在的話)。之前在 Unix 系統和使用純粹 Go 解析時,LookupCNAME
會在 CNAME
記錄所指的名稱沒有 A
、AAAA
或 CNAME
記錄時傳回錯誤。這次變更有將 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
的變更,並在檔案變更時重新載入該檔案。檢查次數每 5 秒最多一次,匹配之前對 /etc/hosts
和 /etc/resolv.conf
的處理方式。
net/http
ResponseWriter.WriteHeader
函數現在支援傳送 1xx
狀態碼。
新的 Server.DisableGeneralOptionsHandler
組態設定可用於停用預設的 OPTIONS *
處理函式。
當 Transport
從代理伺服器收到 CONNECT
請求的 HTTP 回應時,就會呼叫新的 Transport.OnProxyConnectResponse
掛鉤。
HTTP 伺服器現在會接受包含主體的 HEAD 請求,而不是將其拒絕為無效請求。
net/http
函數傳回的 HTTP/2 串流錯誤可以使用 errors.As
轉換為 golang.org/x/net/http2.StreamError
。
cookie 名稱的前導和尾隨空白會被移除,而不是拒絕為無效名稱。例如,cookie 設定 “name =value” 現在會被接受為設定 cookie “name”。
Cookie
的 Expires 欄位為空時,現在會視為有效。Cookie.Valid
僅在設定為 Expires 時會檢查該欄位。
net/netip
新的 IPv6LinkLocalAllRouters
和 IPv6Loopback
函式是 net.IPv6loopback
和 net.IPv6linklocalallrouters
在 net/netip
中的對應函式。
作業系統
在 Windows 上,名稱 NUL
不再是 Mkdir
和 Stat
中的特殊情況。
在 Windows 上,如果檔案為目錄,File.Stat
現在會使用檔案控制代碼來擷取屬性。先前它會使用傳遞給 Open
的路徑,如果檔案已被移動或取代,此路徑可能不再是檔案控制代碼代表的檔案。這樣的變更會修改 Open
在沒有 FILE_SHARE_DELETE
存取權的情況下開啟目錄,其行為與一般檔案一致。
在 Windows 上,File.Seek
現在支援搜尋到目錄的開頭。
作業系統/執行
新的 Cmd
欄位 Cancel
和 WaitDelay
會指定 Cmd
在關閉其相關的 Context
或處理程序於子處理程序仍持有 I/O 管道的情況下結束時之行為。
路徑/檔案路徑
新的錯誤 SkipAll
會立即終止 Walk
,但執行成功。
新的 IsLocal
函式會回報路徑是否在語彙上與目錄有關。例如,如果 IsLocal(p)
為 true
,則 Open(p)
會參照語彙上位於目前目錄根子樹之下的檔案。
反射
新的 Value.Comparable
和 Value.Equal
方法可以用於比較兩個 Value
是否相等。Comparable
會回報 Equal
是否為針對給定 Value
接收器有效的運算。此外,Equal
會回報兩個 Value
是否相等。
新的 Value.Grow
方法會延伸分割片以確保有空間可以再放進 n
個元素。
新的 Value.SetZero
方法會設定值為其類型所指定的零值。
Go 1.18 推出了 Value.SetIterKey
和 Value.SetIterValue
方法。這是優化項目:v.SetIterKey(it)
會被視為等於 v.Set(it.Key())
。執行錯誤地省略了未外傳欄位的檢查,而該檢查存在於未最佳化的表單中。Go 1.20 修正了這些方法,以加入未外傳欄位的檢查。
正規表示式
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
)、總體 mutex 阻塞時間 (/sync/mutex/wait/total:seconds
),以及垃圾收集所花費時間的各種測量值。
基於時間的直方圖指標現在較不精確,但佔用的記憶體大幅減少。
runtime/pprof
目前 Mutex 輪廓樣本經過預先調整,修復了在執行過程中抽樣速率改變時,舊的 mutex 輪廓樣本會調整不正確的問題。
在 Windows 上收集的輪廓現在包含記憶體對應資訊,這修復了與位置無關二進位檔的符號化問題。
runtime/trace
垃圾收集器的背景掃描程式現在較不頻繁地讓出,導致執行跡象中有更少無關的事件。
strings
新的 CutPrefix
和 CutSuffix
函式類似於 TrimPrefix
和 TrimSuffix
,但也會回報字串是否有被裁切。
sync
新的 Map
方法 Swap
、CompareAndSwap
和 CompareAndDelete
允許現有的映射條目以原子方式更新。
syscall
在 FreeBSD 上,FreeBSD 11 和更早版本所需的相容性墊片已被移除。
在 Linux 上,定義了其他 CLONE_*
常數,供與 SysProcAttr.Cloneflags
欄位一起使用。
在 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
。