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 編譯器不接受使用預先宣告函式
real
、imag
和complex
的類型參數類型的引數。我們希望在未來的版本中移除這個限制。 -
只有當方法
m
由P
的限制介面明確宣告時,Go 編譯器才支援在類型參數類型P
的值x
上呼叫方法m
。類似地,方法值x.m
和方法式P.m
也只有在m
由P
明確宣告時才受到支援,即使m
可能因P
中的所有類型實作m
而存在於P
的方法集中。我們希望在未來的版本中移除這個限制。 -
Go 編譯器不支援存取結構欄位
x.f
,其中x
屬於類型參數類型,即使類型參數的類型集合中的所有類型都有欄位f
。我們可能會在未來的版本中移除這個限制。 - 禁止將類型參數或指向類型參數的指標嵌入為結構類型的未命名欄位。類似地,禁止將類型參數嵌入為介面類型的欄位。目前尚不清楚這些是否會在未來被允許。
- 有多個成員的聯合元素不可包含方法集非空的介面類型。目前尚不清楚這些是否會在未來被允許。
泛型也代表著 Go 生態系統的一個重大變革。雖然我們已經更新了幾個核心工具以提供泛型支援,但還有很多事情要做。剩餘的工具、文件和函式庫需要時間才能趕上這些語言變更。
錯誤修正
在函式字面中設定但從未使用的變數,Go 1.18 編譯器現在會正確報告 宣告但未使用
錯誤。在 Go 1.18 之前,編譯器不會在這種情況下報告錯誤。這修正了長久存在的編譯器問題 #8560。因為這個變更,(可能不正確的)程式可能無法再編譯。必要的修正很直接:如果程式確實不正確,請修正程式,或使用有問題的變數,例如將其指定給空白識別碼 _
。由於 go vet
始終會點出此錯誤,受影響的程式數量可能非常少。
在將如 '1' << 32
的符文常數運算式作為引數傳遞給預先宣告的函式 print
和 println
時,Go 1.18 編譯器現在會報告溢位,這與使用者定義函式的行為一致。在 Go 1.18 之前,編譯器不會在這種情況下報告錯誤,但如果符文常數引數適用於 int64
,編譯器會默默接受這些常數引數。因為這個變更,(可能不正確的)程式可能無法再編譯。必要的修正很直接:如果程式確實不正確,請修正程式,或明確地將有問題的引數轉換為正確的類型。由於 go vet
始終會點出此錯誤,受影響的程式數量可能非常少。
相容性
AMD64
Go 1.18 引進新的 GOAMD64
環境變數,在編譯時選擇 AMD64 架構的最低目標版本。允許的值為 v1
、v2
、v3
或 v4
。每個較高層級都需要且利用額外的處理器功能。可以在 此處 找到詳細說明。
GOAMD64
環境變數預設為 v1
。
RISC-V
Linux 上的 64 位元 RISC-V 架構(linux/riscv64
相容性)現在支援 c-archive
和 c-shared
建置模式。
Linux
Go 1.18 需要 Linux kernel 版本 2.6.32 或更新版本。
Windows
windows/arm
和 windows/arm64
相容性現在支援非合作時期搶佔,將該功能納入所有 4 個 Windows 相容性,希望這能解決在呼叫會長時間封鎖的 Win32 函式時遇到的子錯誤。
iOS
在 iOS(ios/arm64
相容性)和執行於基於 AMD64 的 macOS 上的 iOS 模擬器(ios/amd64
相容性)上,Go 1.18 現在需要 iOS 12 或更新版本;停止了對先前版本的支援。
FreeBSD
Go 1.18 是在 FreeBSD 11.x 上獲得支援的最後版本,而 FreeBSD 11.x 現已進入產品生命週期終止階段。Go 1.19 會需要 FreeBSD 12.2+ 或 FreeBSD 13.0+。FreeBSD 13.0+ 會需要設定了 COMPAT_FREEBSD12 選項的 kernel(這是預設)。
工具
模糊測試
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
install
和 go
get
提供安裝說明。現在在模組外使用 go
get
時會回報錯誤,因為沒有 go.mod
檔案可以更新。在 GOPATH 模式中(搭配 GO111MODULE=off
),go
get
仍會如之前一樣建置和安裝套件。
自動 go.mod
和 go.sum
更新
go
mod
graph
、go
mod
vendor
、go
mod
verify
和 go
mod
why
子指令不再自動更新 go.mod
和 go.sum
檔案。(這些檔案可以使用 go
get
、go
mod
tidy
或 go
mod
download
明確更新。)
go
version
go
指令現在會在二進制檔中內嵌版本控制資訊。它包括當前簽出的版本、提交時間,以及一個標示是否存在已編輯或未追蹤檔案的旗標。如果是在 Git、Mercurial、Fossil 或 Bazaar 保存庫內的目錄中呼叫 go
指令,且 main
套件及其包含的主模組在同一個保存庫中時,就會內嵌版本控制資訊。可以使用旗標 -buildvcs=false
來省略此資訊。
另外,go
命令會內嵌建置資訊,包括建置和工具標記(設定為 -tags
)、編譯器、組譯器和連結器旗標(例如 -gcflags
),cgo 是否啟用,如果是的話,會包含 cgo 環境變數的值(例如 CGO_CFLAGS
)。版本控制系統和建置資訊都可以使用 go
version
-m
file
或 runtime/debug.ReadBuildInfo
(用於目前的執行二進位檔)或新的 debug/buildinfo
套件來與模組資訊一起讀取。
內嵌建置資訊的基本資料格式可能會隨著新的 go 發行而變更,因此較舊版本的 go
可能無法處理使用較新版本的 go
製作的建置資訊。要從使用 go
1.18 建置的二進位檔中讀取版本資訊,請使用 go
version
命令和 debug/buildinfo
套件,版本至少為 go
1.18+。
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
命令現在支援「Workspace」模式。如果在工作目錄或父目錄中找到 go.work
檔案,或使用 GOWORK
環境變數指定一個,它會將 go
命令置於工作空間模式中。在工作空間模式中,將使用 go.work
檔案確定作為模組解析根目錄的主模組集合,而不是使用通常找到的 go.mod
檔案來指定單一主模組。如需更多資訊,請參閱 go work
文件。
go
build
-asan
go
build
命令和相關命令現在支援 -asan
旗標,啟用與使用地址掃描程式 (C 編譯器選項 -fsanitize=address
) 編譯的 C (或 C++) 程式碼之間的互通作業。
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
檢查器 copylock
、printf
、sortslice
、testinggoroutine
和 tests
都有中度的精準度改善,以處理其他程式碼模式。這可能會導致在現有封包中回報新的錯誤。例如,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=ppc64
、ppc64le
) 以及所有作業系統上的 64 位元 x86 架構 (GOARCH=amd64
)。在 64 位元 ARM 和 64 位元 PowerPC 系統中,基準測試顯示典型的效能改善 10% 或更多。
如同 Go 1.17 發行說明中的 所述,此變更不會影響任何安全 Go 程式碼的功能,且設計上對大多數組合語言程式碼不會有任何影響。請參閱 Go 1.17 發行說明 以取得更多詳細資訊。
現在編譯器可以內嵌包含範圍迴圈或標籤迴圈的函式。
新的 -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 或更新的開機工具鏈。現在,在回歸 $HOME/go1.4
之前,Go 會先尋找 $HOME/go1.17
或 $HOME/sdk/go1.17
。我們計畫讓 Go 1.19 要求開機使用 Go 1.17 或更新版本,而此變更應可讓轉換更順利。如需更多詳細資料,請參閱 go.dev/issue/44505。
標準程式庫
新的 debug/buildinfo
套件
新的 debug/buildinfo
套件提供存取透過 go
命令建立的可執行檔中內嵌的模組版本、版本控制資訊和建立旗標之功能。相同的資訊也可透過 runtime/debug.ReadBuildInfo
供目前執行的二進位檔使用,或透過 command line 上的 go
version
-m
使用。
新的 net/netip
套件
新的 net/netip
套件定義新的 IP 位址類型 Addr
。與現有的 net.IP
類型相比,netip.Addr
類型佔用的記憶體較少、不可變,而且可比較,因此它支援 ==
,並可用作映射鍵。
除了 Addr
之外,該套件定義了 AddrPort
,表示 IP 和埠,以及 Prefix
,表示網路 CIDR 前置詞。
此套件也定義了數個函式來建立並檢查這些新類型:AddrFrom4
、AddrFrom16
、AddrFromSlice
、AddrPortFrom
、IPv4Unspecified
、IPv6LinkLocalAllNodes
、IPv6Unspecified
、MustParseAddr
、MustParseAddrPort
、MustParsePrefix
、ParseAddr
、ParseAddrPort
、ParsePrefix
、PrefixFrom
。
net
套件包括了與現有方法平行的全新方法,但回傳的是 netip.AddrPort
,而非負擔較重的 net.IP
或 *net.UDPAddr
類型:Resolver.LookupNetIP
、UDPConn.ReadFromUDPAddrPort
、UDPConn.ReadMsgUDPAddrPort
、UDPConn.WriteToUDPAddrPort
、UDPConn.WriteMsgUDPAddrPort
。新的 UDPConn
方法支援不配置記憶體分配的 I/O。
net
套件現在也包括了在現有的 TCPAddr
/UDPAddr
類型和 netip.AddrPort
之間進行轉換的函式和方法:TCPAddrFromAddrPort
、UDPAddrFromAddrPort
、TCPAddr.AddrPort
、UDPAddr.AddrPort
。
TLS 1.0 和 1.1 在預設情況下在客戶端停用
如果 Config.MinVersion
未設定,那麼現在預設為 TLS 1.2 進行客戶端連線。預期任何安全的最新伺服器都會支援 TLS 1.2,而瀏覽器則自 2020 年起就要求支援它。TLS 1.0 和 1.1 仍受到支援,只要將 Config.MinVersion
設定為 VersionTLS10
即可。伺服器端的預設值則保持不變,為 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
環境變數暫時還原。此選項將在未來的版本中移除。
程式庫中的微小變更
如同以往,程式庫中包含 çeşitli微小變更和更新,並考量到了 Go 1 相容性承諾。
bufio
新的 Writer.AvailableBuffer
方法傳回一個具有可能非空容量的空緩衝區,以用於類似附加的 API。追加後,可以將緩衝區提供給後續的 Write
呼叫,且可能避免任何複製。
針對具有 nil
緩衝區的物件呼叫時,Reader.Reset
和 Writer.Reset
方法現在會使用預設緩衝區大小。
bytes
新的 Cut
函式會針對分隔符號來切片一個 []byte
。它可以取代並簡化許多 Index
、IndexByte
、IndexRune
和 SplitN
的常見用途。
Trim
、TrimLeft
和 TrimRight
現在沒有配置,且針對小型 ASCII 剪裁組來說特別快上 10 倍。
Title
函式現已過期。它不會處理 Unicode 標點符號和語言特定的大小寫規則,而且被 golang.org/x/text/cases 套件取代。
crypto/elliptic
P224
、P384
和 P521
曲線實作現在都由下列專案產生的程式碼提供後援:addchain 和 fiat-crypto,後者基於算術運算的正式驗證模型。它們現在使用更安全的完全公式和內部 API。P-224 和 P-384 現在快上約四倍。所有特定曲線實作現在都是定時 (constant-time) 執行。
作業於無效的曲線點 (IsOnCurve
方法傳回 false 的點,且從未由 Unmarshal
或作業於有效點的 Curve
方法傳回) 一直都是未定義的行為,可能會導致重要金鑰復原攻擊,現在新的後端不支援這些曲線點。如果提供無效點給 P224
、P384
或 P521
方法,該方法現在會傳回隨機點。此行為可能在未來的版本中變更為明確的恐慌 (panic)。
crypto/tls
新的 Conn.NetConn
方法允許存取基礎的 net.Conn
。
crypto/x509
Certificate.Verify
現在使用平台 API 在使用空白 VerifyOpts.Roots
呼叫時或使用從 SystemCertPool
傳回的根群集時驗證 macOS 和 iOS 上的憑證有效性。
SystemCertPool
現在在 Windows 上提供。
在 Windows、macOS、以及 iOS 上,當 CertPool
由 SystemCertPool
傳回並增加其他憑證時,Certificate.Verify
會執行兩次驗證:一次使用平台驗證器 API 和系統根,另一次使用 Go 驗證器和額外根。由平台驗證器 API 傳回的鏈條會優先處理。
CertPool.Subjects
已棄用。在 Windows、macOS、以及 iOS 上,由 SystemCertPool
傳回的 CertPool
將傳回一個群集,不包含 Subjects
傳回的片段中的系統根,因為靜態清單無法適當地表示平台政策,而且可能無法透過平台 API 提供。
在 Go 1.19 中可能會移除使用依賴於 MD5 雜湊的簽章演算法 (MD5WithRSA
) 來簽署憑證的功能。
debug/dwarf
StructField
和 BasicType
結構現在都有 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
套件進行以下新增:
FuncType
和TypeSpec
節點有一個新的欄位TypeParams
來儲存型別參數 (若有)。- 新的運算式節點
IndexListExpr
表示具有多個索引的索引運算式,在使用多個明確型別參數來實例化函數和型別時使用。
go/constant
新的 Kind.String
方法會傳回接收器型別的人類可讀取的名稱。
go/token
按照建議新增常數 TILDE
,表示 ~
符號 新增 go/ast 和 go/token 以支援參數化函式和類型 。
go/types
新的 Config.GoVersion
欄位設定已接受的 Go 語言版本。
配合建議 新增 go/types 以支援類型參數 ,向 go/types
套件新增以下內容
- 新增類型
TypeParam
、工廠函式NewTypeParam
及相關方法,用來表示類型參數。 - 新增類型
TypeParamList
,用來存放類型參數清單。 - 新增類型
TypeList
,用來存放類型清單。 - 新增工廠函式
NewSignatureType
,會配置具有 (接收器或函式) 類型參數的Signature
。若要存取這些類型參數,Signature
類型具有兩個新方法Signature.RecvTypeParams
和Signature.TypeParams
。 Named
類型有四個新方法:Named.Origin
,用來取得已實例化類型的原始參數化類型;Named.TypeArgs
和Named.TypeParams
,用來取得已實例化或參數化類型的類型引數或類型參數;Named.SetTypeParams
,用來設定類型參數 (例如,導入命名類型,而無法同時配置命名類型並設定類型參數,因為可能會形成迴圈)。Interface
類型有四個新方法:Interface.IsComparable
和Interface.IsMethodSet
,用來查詢介面定義的類型集合的屬性;Interface.MarkImplicit
和Interface.IsImplicit
,用來設定並測試介面是否為類型約束文字陳述周圍的隱式介面。- 新增類型
Union
和Term
、工廠函式NewUnion
和NewTerm
及相關方法,用來表示介面中的類型集合。 - 新增函式
Instantiate
,用來實例化參數化類型。 - 新增的
Info.Instances
地圖會透過新的Instance
類型記錄函式和類型實例化。 -
新增的類型
ArgumentError
及相關方法,用來表示與類型引數相關的錯誤。 -
新增的
Context
型別和工廠函式NewContext
透過新的Config.Context
欄位,便利分享型別檢查過的套件中相等的型別實例。
謂詞 AssignableTo
、ConvertibleTo
、Implements
、Identical
、IdenticalIgnoreTags
和 AssertableTo
現在也能搭配一般化的介面作為引數,亦即只能在 Go 程式碼中作為型別限制的介面。請注意,對於未實例化的泛型型別,AssignableTo
、ConvertibleTo
、Implements
和 AssertableTo
的行為是未定義的,且如果第一個引數是一般化的介面,AssertableTo
也是未定義的。
html/template
在 range
管道中,新的 {{break}}
指令會提早結束迴圈,新的 {{continue}}
指令會立即開始下一個迴圈迭代。
and
函式不再總是評估所有引數;它會在第一個評估為 false 的引數之後停止評估引數。類似地,or
函式現在會在第一個評估為 true 的引數之後停止評估引數。如果任一引數是函式呼叫,這就會有所不同。
image/draw
當引數不是最常見的影像型別時,備援實作 (Draw
和 DrawMask
) 的執行速度已加快,此時這些引數會實作 Go 1.17 新增的選用介面 draw.RGBA64Image
和 image.RGBA64Image
。
net
net.Error.Temporary
已標示為已棄用。
net/http
在 WebAssembly 目標上,如果已指定 Transport
中的 Dial
、DialContext
、DialTLS
和 DialTLSContext
方法欄位,它們現在會正確使用來建立 HTTP 要求。
新的 Cookie.Valid
方法會回報 Cookie 是否有效。
新的 MaxBytesHandler
函式會建立一個 Handler
,它會用一個 MaxBytesReader
來包裝它的 ResponseWriter
和 Request.Body
。
當查詢含有非 ASCII 字元的網域名稱時,Unicode 至 ASCII 轉換現已依照非過渡式處理方式,定義於 Unicode IDNA 相容性處理 標準 (UTS #46)。四個特殊符號的詮釋有變更: ß、ς、零寬連接符號 U+200D 和零寬不連接符號 U+200C。非過渡式處理與大多數應用程式和網頁瀏覽器相容。
os/user
User.GroupIds
現使用 Go 的原生實作,cgo 不可用時。
reflect
新的 Value.SetIterKey
和 Value.SetIterValue
方法會使用對應 iter 的 map 來設定 Value。它們相當於 Value.Set(iter.Key())
和 Value.Set(iter.Value())
,不過會減少一些分配。
新的 Value.UnsafePointer
方法會將 Value 的值返回為 unsafe.Pointer
。這讓呼叫方能夠從 Value.UnsafeAddr
和 Value.Pointer
進行移轉,以消除呼叫點在 uintptr 至 unsafe.Pointer 轉換時所需執行的步驟(為 unsafe.Pointer 規則所要求)。
新的 MapIter.Reset
方法變更其接收器以重複 iter 不同的 map。使用 MapIter.Reset
可以不需分配記憶體的方式,重複 iter 多個 map。
已新增多個方法 ( Value.CanInt
、Value.CanUint
、Value.CanFloat
、Value.CanComplex
) 至 Value
,用於測試轉換是否安全。
已新增 Value.FieldByIndexErr
以避免 stepping through nil pointer 至 embedded struct 時在 Value.FieldByIndex
中發生的 panic。
reflect.Ptr
和 reflect.PtrTo
已分別重新命名為 reflect.Pointer
和 reflect.PointerTo
,使之與其他 reflect 套件一致。舊的命名會持續使用,但在之後的 Go 版本中將會被棄用。
regexp
regexp
現將 UTF-8 字串中的每個無效位元組視為 U+FFFD
。
runtime/debug
BuildInfo
結構體有兩個新的欄位,含有關於如何建置二進位檔的額外資訊
GoVersion
保存建置二進位檔時所使用的 Go 版本。Settings
是BuildSettings
結構體的切片,保存描述建置的鍵值對。
runtime/pprof
在 Linux 上,CPU 分析器現已支援每個執行緒的計時器。這將增加分析可觀察到的最大 CPU 使用量,並減少部分形式的偏差。
strconv
strconv.Unquote
現已拒絕 Unicode 替代字元的一半。
strings
新的 Cut
函數會依分隔符號切片 字串
。它可以取代並簡化 Index
、IndexByte
、IndexRune
和 SplitN
的許多常見用途。
新的 Clone
函數會複製輸入的 字串
,而所傳回的已複製 字串
並不會參照輸入字串的記憶體。
Trim
、TrimLeft
和 TrimRight
現已無配置空間,且特別是對於小型 ASCII 字元,效能已提高達 10 倍。
Title
函數現已停用。它無法處理 Unicode 標點符號和特定語言的大寫化規則,並已由 golang.org/x/text/cases 套件所取代。
sync
新的方法 Mutex.TryLock
、RWMutex.TryLock
和 RWMutex.TryRLock
將會取得鎖,但前提是該鎖目前並未持有。
syscall
Windows 已推出新的函數 SyscallN
,支援透過任意數量的參數進行呼叫。因此,Syscall
、Syscall6
、Syscall9
、Syscall12
、Syscall15
和 Syscall18
已停用,並改採用 SyscallN
。
SysProcAttr.Pdeathsig
現已支援 FreeBSD。
syscall/js
已移除 Wrapper
介面。
testing
已提升 /
在 -run
和 -bench
參數中的優先順序。A/B|C/D
過去視為 A/(B|C)/D
,現在則視為 (A/B)|(C/D)
。
如果-run
選項未選擇任何測試,則會略過-count
選項。在測試函式每次執行時更改每次執行的子測試組的測試改變的情況下(這可能性極低),這可能會變更現有測試的行為。
新的 testing.F
類型由上面所述的新 fuzzing 支援 使用。測試現在也支援命令列選項 -test.fuzz
、-test.fuzztime
和 -test.fuzzminimizetime
。
text/template
在 range
管道中,新的 {{break}}
指令會提早結束迴圈,新的 {{continue}}
指令會立即開始下一個迴圈迭代。
and
函式不再總是評估所有引數;它會在第一個評估為 false 的引數之後停止評估引數。類似地,or
函式現在會在第一個評估為 true 的引數之後停止評估引數。如果任一引數是函式呼叫,這就會有所不同。
text/template/parse
此套件支援新的 text/template 和 html/template 的 {{break}}
命令,透過新的常數 NodeBreak
和新的類型 BreakNode
,並同樣以新的常數 NodeContinue
和新的類型 ContinueNode
支援新的 {{continue}}
命令。
unicode/utf8
新的 AppendRune
函式會將 rune
的 UTF-8 編碼新增至 []byte
。