Go 1.17 釋出說明

Go 1.17 簡介

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

語言變化

Go 1.17 包含對語言的三個小改進。

  • 從切片到陣列指標的轉換:型別為 []T 的表示式 s 現在可以轉換為陣列指標型別 *[N]T。如果 a 是此類轉換的結果,那麼在範圍內的相應索引將引用相同的底層元素:&a[i] == &s[i] 對於 0 <= i < N。如果 len(s) 小於 N,則轉換會發生 panic。
  • unsafe.Addunsafe.Add(ptr, len)len 新增到 ptr 並返回更新後的指標 unsafe.Pointer(uintptr(ptr) + uintptr(len))
  • unsafe.Slice:對於型別為 *T 的表示式 ptrunsafe.Slice(ptr, len) 返回一個型別為 []T 的切片,其底層陣列從 ptr 開始,長度和容量為 len

新增 unsafe 包的增強功能是為了簡化編寫符合 unsafe.Pointer 安全規則的程式碼,但這些規則保持不變。特別是,正確使用 unsafe.Pointer 的現有程式仍然有效,新程式在使用 unsafe.Addunsafe.Slice 時仍必須遵循這些規則。

請注意,新的切片到陣列指標的轉換是型別轉換在執行時可能發生 panic 的第一個案例。假設型別轉換永遠不會發生 panic 的分析工具應更新以考慮這種可能性。

移植

Darwin

如 Go 1.16 釋出說明中宣佈,Go 1.17 需要 macOS 10.13 High Sierra 或更高版本;對先前版本的支援已停止。

Windows

Go 1.17 增加了對 Windows 上的 64 位 ARM 架構(windows/arm64 埠)的支援。此埠支援 cgo。

OpenBSD

OpenBSD 上的 64 位 MIPS 架構(openbsd/mips64 埠)現在支援 cgo。

在 Go 1.16 中,OpenBSD 上的 64 位 x86 和 64 位 ARM 架構(openbsd/amd64openbsd/arm64 埠)透過 libc 進行系統呼叫,而不是直接使用機器指令。在 Go 1.17 中,OpenBSD 上的 32 位 x86 和 32 位 ARM 架構(openbsd/386openbsd/arm 埠)也採用了這種方式。這確保了與 OpenBSD 6.9 及更高版本的相容性,OpenBSD 6.9 及更高版本要求非靜態 Go 二進位制檔案透過 libc 進行系統呼叫。

ARM64

Go 程式現在在所有作業系統的 64 位 ARM 架構上維護堆疊幀指標。以前,堆疊幀指標只在 Linux、macOS 和 iOS 上啟用。

loong64 GOARCH 值已保留

主 Go 編譯器尚未支援 LoongArch 架構,但我們已保留 GOARCH 值“loong64”。這意味著 Go 工具現在將忽略名為 *_loong64.go 的 Go 檔案,除非正在使用該 GOARCH 值。

工具

Go 命令

go 1.17 模組中修剪過的模組圖

如果模組指定 go 1.17 或更高版本,則模組圖只包含其他 go 1.17 模組的*直接*依賴項,而不是其完整的傳遞依賴項。(有關詳細資訊,請參閱模組圖修剪。)

為了讓 go 命令使用修剪後的模組圖正確解析傳遞匯入,每個模組的 go.mod 檔案需要包含有關與該模組相關的傳遞依賴項的更多詳細資訊。如果模組在其 go.mod 檔案中指定 go 1.17 或更高版本,則其 go.mod 檔案現在包含為每個提供傳遞匯入包的模組顯式require 指令。(在以前的版本中,go.mod 檔案通常只包含*直接*匯入包的顯式要求。)

由於模組圖修剪所需的擴充套件 go.mod 檔案包含載入主模組中任何包的匯入所需的所有依賴項,如果主模組指定 go 1.17 或更高版本,則 go 工具不再讀取(甚至下載)依賴項的 go.mod 檔案,如果它們不是完成請求命令所必需的。(請參閱延遲載入。)

由於擴充套件的 Go 1.17 go.mod 檔案中顯式要求的數量可能大大增加,因此在 go 1.17 模組中新新增的對*間接*依賴項的要求將與包含直接依賴項的塊分開維護在一個單獨的 require 塊中。

為方便升級到 Go 1.17 修剪後的模組圖,go mod tidy 子命令現在支援 -go 標誌,用於設定或更改 go.mod 檔案中的 go 版本。要將現有模組的 go.mod 檔案轉換為 Go 1.17,而不更改其依賴項的選定版本,請執行

  go mod tidy -go=1.17

預設情況下,go mod tidy 會驗證與主模組相關的依賴項的選定版本是否與先前 Go 版本(對於指定 go 1.17 的模組,為 Go 1.16)使用的版本相同,並保留該版本所需的 go.sum 條目,即使是對於其他命令通常不需要的依賴項。

-compat 標誌允許覆蓋該版本以支援舊版本(或只支援新版本),直至 go.mod 檔案中 go 指令指定的版本。要僅為 Go 1.17 整理 go 1.17 模組,而不儲存 Go 1.16 的校驗和(或檢查與 Go 1.16 的一致性)

  go mod tidy -compat=1.17

請注意,即使主模組已透過 -compat=1.17 進行了整理,從 go 1.16 或更早版本模組中 require 該模組的使用者仍然可以使用它,前提是這些包僅使用相容的語言和庫功能。

go mod graph 子命令也支援 -go 標誌,這使得它報告由指定 Go 版本看到的圖,顯示可能被修剪掉的依賴項。

模組棄用評論

模組作者可以透過向 go.mod 新增 // Deprecated: 註釋,然後標記新版本來棄用模組。如果命令列中指定的包所需的模組已棄用,go get 現在會列印警告。go list -m -u 列印所有依賴項的棄用資訊(使用 -f-json 顯示完整訊息)。go 命令將不同的主版本視為不同的模組,因此此機制可用於例如向用戶提供新主版本的遷移說明。

go get

go get -insecure 標誌已棄用並已刪除。要允許在獲取依賴項時使用不安全的方案,請使用 GOINSECURE 環境變數。-insecure 標誌也繞過了模組校驗和驗證,如果您需要該功能,請使用 GOPRIVATEGONOSUMDB。有關詳細資訊,請參閱 go help environment

在主模組之外安裝命令(不帶 -d 標誌)時,go get 會列印棄用警告。應改用 go install cmd@version 來安裝特定版本的命令,使用 @latest@v1.2.3 等字尾。在 Go 1.18 中,-d 標誌將始終啟用,go get 將僅用於更改 go.mod 中的依賴項。

go.mod 檔案缺少 go 指令

如果主模組的 go.mod 檔案不包含 go 指令,並且 go 命令無法更新 go.mod 檔案,則 go 命令現在假定為 go 1.11 而不是當前版本。(go mod init 自 Go 1.12 以來已自動新增 go 指令。)

如果模組依賴項缺少顯式的 go.mod 檔案,或者其 go.mod 檔案不包含 go 指令,則 go 命令現在假定該依賴項為 go 1.16 而不是當前版本。(在 GOPATH 模式下開發的依賴項可能缺少 go.mod 檔案,並且 vendor/modules.txt 迄今為止從未記錄依賴項 go.mod 檔案指示的 go 版本。)

vendor 內容

如果主模組指定 go 1.17 或更高版本,go mod vendor 現在會使用每個 vendored 模組在其自己的 go.mod 檔案中指示的 go 版本來註釋 vendor/modules.txt。從 vendored 原始碼構建模組的包時,將使用註釋的版本。

如果主模組指定 go 1.17 或更高版本,go mod vendor 現在會省略 vendored 依賴項的 go.modgo.sum 檔案,否則這可能會干擾 go 命令在 vendor 樹中呼叫時識別正確模組根的能力。

密碼提示

go 命令現在預設在透過 SSH 獲取 Git 倉庫時抑制 SSH 密碼提示和 Git 憑據管理器提示,就像它以前對其他 Git 密碼提示所做的那樣。使用受密碼保護的 SSH 向私有 Git 倉庫進行身份驗證的使用者可以配置 ssh-agent,以使 go 命令能夠使用受密碼保護的 SSH 金鑰。

go mod download

當不帶引數呼叫 go mod download 時,它將不再儲存下載模組內容的校驗和到 go.sum。它仍然可能對 go.modgo.sum 進行必要的更改以載入構建列表。這與 Go 1.15 中的行為相同。要儲存所有模組的校驗和,請使用 go mod download all

//go:build

go 命令現在理解 //go:build 行並優先於 // +build 行。新語法使用布林表示式,就像 Go 一樣,應該更不容易出錯。截至此版本,新語法已完全支援,所有 Go 檔案都應更新為具有相同含義的兩種形式。為了幫助遷移,gofmt 現在會自動同步這兩種形式。有關語法和遷移計劃的更多詳細資訊,請參閱 https://golang.com.tw/design/draft-gobuild

go run

go run 現在接受帶有版本字尾的引數(例如,go run example.com/cmd@v1.0.0)。這使得 go run 在模組感知模式下構建和執行包,忽略當前目錄或任何父目錄中的 go.mod 檔案(如果存在)。這對於執行可執行檔案而無需安裝它們或無需更改當前模組的依賴項很有用。

Gofmt

gofmt (和 go fmt) 現在將 //go:build 行與 // +build 行同步。如果檔案只有 // +build 行,它們將被移動到檔案中的適當位置,並新增匹配的 //go:build 行。否則,// +build 行將根據任何現有的 //go:build 行進行覆蓋。有關更多資訊,請參閱 https://golang.com.tw/design/draft-gobuild

Vet

//go:build// +build 行不匹配的新警告

vet 工具現在驗證 //go:build// +build 行是否在檔案的正確部分並相互同步。如果不是,可以使用gofmt來修復它們。有關更多資訊,請參閱 https://golang.com.tw/design/draft-gobuild

對非緩衝通道呼叫 signal.Notify 的新警告

vet 工具現在會警告對 signal.Notify 的呼叫,其中傳入訊號被髮送到非緩衝通道。使用非緩衝通道存在丟失訊號的風險,因為 signal.Notify 在傳送到通道時不會阻塞。例如

c := make(chan os.Signal)
// signals are sent on c before the channel is read from.
// This signal may be dropped as c is unbuffered.
signal.Notify(c, os.Interrupt)

signal.Notify 的使用者應使用具有足夠緩衝空間的通道,以跟上預期的訊號速率。

Is、As 和 Unwrap 方法的新警告

vet 工具現在會警告實現 error 介面的型別上命名為 AsIsUnwrap 的方法,這些方法的簽名與 errors 包預期的簽名不同。errors.{As,Is,Unwrap} 函式期望這些方法分別實現 Is(error) boolAs(interface{}) boolUnwrap() errorerrors.{As,Is,Unwrap} 函式將忽略同名但簽名不同的方法。例如

type MyError struct { hint string }
func (m MyError) Error() string { ... } // MyError implements error.
func (MyError) Is(target interface{}) bool { ... } // target is interface{} instead of error.
func Foo() bool {
    x, y := MyError{"A"}, MyError{"B"}
    return errors.Is(x, y) // returns false as x != y and MyError does not have an `Is(error) bool` function.
}

覆蓋率

cover 工具現在使用 golang.org/x/tools/cover 中的最佳化解析器,在解析大型覆蓋率配置檔案時可能會明顯更快。

編譯器

Go 1.17 實現了一種新的函式引數和結果傳遞方式,使用暫存器而不是堆疊。針對一組代表性的 Go 包和程式的基準測試顯示,效能提高了約 5%,二進位制檔案大小通常減少約 2%。目前,這已在 64 位 x86 架構上的 Linux、macOS 和 Windows(linux/amd64darwin/amd64windows/amd64 埠)上啟用。

此更改不影響任何安全 Go 程式碼的功能,旨在對大多數彙編程式碼沒有影響。它可能會影響在訪問函式引數時違反 unsafe.Pointer 規則,或依賴涉及比較函式程式碼指標的未文件行為的程式碼。為了保持與現有彙編函式的相容性,編譯器會生成介面卡函式,在新基於暫存器的呼叫約定和以前基於堆疊的呼叫約定之間進行轉換。這些介面卡通常對使用者是不可見的,但透過 reflect.ValueOf(fn).Pointer()unsafe.Pointer 在彙編程式碼中獲取 Go 函式的地址或在 Go 程式碼中獲取彙編函式的地址現在將返回介面卡的地址。依賴這些程式碼指標值的程式碼可能不再按預期執行。介面卡還可能在兩種情況下導致非常小的效能開銷:透過 func 值從 Go 間接調用匯編函式,以及從彙編呼叫 Go 函式。

執行時(當發生未捕獲的 panic 或呼叫 runtime.Stack 時列印)的堆疊跟蹤格式得到了改進。以前,函式引數以基於記憶體佈局的十六進位制單詞列印。現在,原始碼中的每個引數都單獨列印,用逗號分隔。聚合型別(結構體、陣列、字串、切片、介面和複雜型別)的引數用大括號分隔。需要注意的是,僅存在於暫存器中且未儲存到記憶體中的引數值可能不準確。函式返回值(通常不準確)不再列印。

包含閉包的函式現在可以內聯。此更改的一個影響是,包含閉包的函式可能會為函式內聯的每個位置生成不同的閉包程式碼指標。Go 函式值不能直接比較,但此更改可能會揭示使用 reflectunsafe.Pointer 繞過此語言限制並按程式碼指標比較函式的程式碼中的錯誤。

當連結器使用外部連結模式時(這是連結使用 cgo 的程式的預設模式),並且連結器使用 -I 選項呼叫時,該選項現在將作為 -Wl,--dynamic-linker 選項傳遞給外部連結器。

標準庫

Cgo

runtime/cgo 包現在提供了一個新功能,允許將任何 Go 值轉換為可以安全地在 C 和 Go 之間傳遞值的安全表示。有關更多資訊,請參閱 runtime/cgo.Handle

URL 查詢解析

net/urlnet/http 包以前除了 "&"(和號)之外,還接受 ";"(分號)作為 URL 查詢中的設定分隔符。現在,帶有未進行百分比編碼的分號的設定將被拒絕,並且 net/http 伺服器在請求 URL 中遇到此類設定時,會向 Server.ErrorLog 記錄警告。

例如,在 Go 1.17 之前,URL example?a=1;b=2&c=3Query 方法會返回 map[a:[1] b:[2] c:[3]],而現在它返回 map[c:[3]]

當遇到這樣的查詢字串時,URL.QueryRequest.FormValue 會忽略任何包含分號的設定,ParseQuery 返回剩餘的設定和一個錯誤,而 Request.ParseFormRequest.ParseMultipartForm 返回一個錯誤,但仍會根據剩餘的設定設定 Request 欄位。

net/http 使用者可以透過使用新的 AllowQuerySemicolons 處理程式包裝器來恢復原始行為。這也會抑制 ErrorLog 警告。請注意,如果不同的系統對快取鍵的解釋不同,接受分號作為查詢分隔符可能會導致安全問題。有關更多資訊,請參閱 問題 25192

TLS 嚴格 ALPN

當設定 Config.NextProtos 時,伺服器現在強制執行配置的協議與客戶端公佈的 ALPN 協議(如果有)之間存在重疊。如果沒有相互支援的協議,則連線將以 no_application_protocol 警報關閉,正如 RFC 7301 所要求的那樣。這有助於緩解 ALPACA 跨協議攻擊

作為例外,當伺服器的 Config.NextProtos 中包含值 "h2" 時,HTTP/1.1 客戶端將被允許連線,就像它們不支援 ALPN 一樣。有關更多資訊,請參閱 問題 46310

對庫的微小更改

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

archive/zip

新的方法 File.OpenRawWriter.CreateRawWriter.Copy 為效能是主要考慮因素的情況提供了支援。

bufio

Writer.WriteRune 方法現在為負的 rune 值寫入替換字元 U+FFFD,就像它對其他無效 rune 值所做的那樣。

bytes

Buffer.WriteRune 方法現在為負的 rune 值寫入替換字元 U+FFFD,就像它對其他無效 rune 值所做的那樣。

compress/lzw

NewReader 函式保證返回新型別 Reader 的值,同樣 NewWriter 保證返回新型別 Writer 的值。這兩個新型別都實現了 Reset 方法(Reader.ResetWriter.Reset),允許重用 ReaderWriter

crypto/ed25519

crypto/ed25519 包已重寫,現在在 amd64 和 arm64 上所有操作的速度大約快了一倍。可觀察到的行為沒有其他改變。

crypto/elliptic

CurveParams 方法現在會在可用時自動為已知曲線(P-224、P-256 和 P-521)呼叫更快、更安全的專用實現。請注意,這是一種盡力而為的方法,應用程式應避免使用通用的、非恆定時間的 CurveParams 方法,而應使用專用的 Curve 實現,例如 P256

P521 曲線實現已使用 fiat-crypto 專案生成的程式碼進行了重寫,該專案基於形式化驗證的算術運算模型。它現在是常數時間,在 amd64 和 arm64 上的速度快了三倍。可觀察到的行為沒有其他改變。

crypto/rand

crypto/rand 包現在在 macOS 上使用 getentropy 系統呼叫,在 Solaris、Illumos 和 DragonFlyBSD 上使用 getrandom 系統呼叫。

crypto/tls

新的 Conn.HandshakeContext 方法允許使用者控制正在進行的 TLS 握手的取消。透過新的 ClientHelloInfo.ContextCertificateRequestInfo.Context 方法,可以在各種回撥中訪問提供的上下文。握手完成後取消上下文沒有效果。

密碼套件排序現在完全由 crypto/tls 包處理。目前,密碼套件根據其安全性、效能和硬體支援進行排序,同時考慮本地和對等方的硬體。Config.CipherSuites 欄位的順序現在被忽略,Config.PreferServerCipherSuites 欄位也是如此。請注意,Config.CipherSuites 仍然允許應用程式選擇要啟用的 TLS 1.0-1.2 密碼套件。

3DES 密碼套件已移至 InsecureCipherSuites,原因是存在基本的塊大小相關弱點。由於上述密碼套件排序的改變,它們仍然預設啟用,但僅作為最後手段。

從下個版本 Go 1.18 開始,crypto/tls 客戶端的 Config.MinVersion 將預設為 TLS 1.2,預設停用 TLS 1.0 和 TLS 1.1。應用程式可以透過顯式設定 Config.MinVersion 來覆蓋此更改。這不會影響 crypto/tls 伺服器。

crypto/x509

CreateCertificate 現在會在提供的私鑰與父級公鑰(如果有)不匹配時返回錯誤。生成的證書將無法驗證。

臨時 GODEBUG=x509ignoreCN=0 標誌已移除。

ParseCertificate 已重寫,現在消耗的資源減少約 70%。處理 WebPKI 證書時的可觀察行為沒有其他改變,除了錯誤訊息。

在 BSD 系統上,現在會搜尋 /etc/ssl/certs 以查詢受信任的根。這增加了對 FreeBSD 12.2+ 中新系統受信任證書儲存的支援。

從下個版本 Go 1.18 開始,crypto/x509 將拒絕使用 SHA-1 雜湊函式簽名的證書。這不適用於自簽名根證書。SHA-1 的實際攻擊已在 2017 年得到證實,並且自 2015 年以來,公共信任的證書頒發機構就沒有再頒發 SHA-1 證書。

database/sql

DB.Close 方法現在會關閉 connector 欄位,如果此欄位中的型別實現了 io.Closer 介面。

新的 NullInt16NullByte 結構體表示可能為 null 的 int16 和 byte 值。它們可以作為 Scan 方法的目標,類似於 NullString。

debug/elf

已新增 SHT_MIPS_ABIFLAGS 常量。

encoding/binary

binary.Uvarint 將在 10 bytes 後停止讀取以避免浪費計算。如果需要超過 10 bytes,則返回的位元組數為 -11
以前的 Go 版本在讀取不正確編碼的 varint 時可能會返回更大的負數。

encoding/csv

新的 Reader.FieldPos 方法返回與 Read 最近返回的記錄中給定欄位的開頭對應的行和列。

encoding/xml

當註釋出現在 Directive 中時,它現在被替換為單個空格,而不是完全省略。

帶有前導、尾隨或多個冒號的無效元素或屬性名稱現在將未修改地儲存到 Name.Local 欄位中。

flag

如果指定了無效名稱,標誌宣告現在會發生 panic。

go/build

新的 Context.ToolTags 欄位儲存與當前 Go 工具鏈配置相適應的構建標籤。

go/format

SourceNode 函式現在將 //go:build 行與 // +build 行同步。如果檔案只有 // +build 行,它們將被移動到檔案中的適當位置,並新增匹配的 //go:build 行。否則,// +build 行將根據任何現有的 //go:build 行進行覆蓋。有關更多資訊,請參閱 https://golang.com.tw/design/draft-gobuild

go/parser

新的 SkipObjectResolution Mode 值指示解析器不將識別符號解析為其宣告。這可能會提高解析速度。

影像

具體的影像型別(RGBAGray16 等)現在實現了一個新的 RGBA64Image 介面。以前實現 draw.Image 的具體型別現在也實現了 image/draw 包中的新介面 draw.RGBA64Image

io/fs

新的 FileInfoToDirEntry 函式將 FileInfo 轉換為 DirEntry

math

math 包現在定義了三個額外的常量:MaxUintMaxIntMinInt。對於 32 位系統,它們的值分別為 2^32 - 12^31 - 1-2^31。對於 64 位系統,它們的值分別為 2^64 - 12^63 - 1-2^63

mime

在 Unix 系統上,MIME 型別表現在會在可用時從本地系統的 共享 MIME-info 資料庫中讀取。

mime/multipart

Part.FileName 現在將 filepath.Base 應用於返回值。這減輕了接受多部分訊息的應用程式中潛在的路徑遍歷漏洞,例如呼叫 Request.FormFilenet/http 伺服器。

net

新的方法 IP.IsPrivate 報告一個地址是否是符合 RFC 1918 的私有 IPv4 地址,或者是否是符合 RFC 4193 的本地 IPv6 地址。

Go DNS 解析器現在在解析僅支援 IPv4 或僅支援 IPv6 的網路的地址時只發送一個 DNS 查詢,而不是同時查詢兩種地址族。

ErrClosed 哨兵錯誤和 ParseError 錯誤型別現在實現了 net.Error 介面。

ParseIPParseCIDR 函式現在會拒絕包含帶有前導零的十進位制元件的 IPv4 地址。這些元件始終被解釋為十進位制,但某些作業系統將它們視為八進位制。這種不匹配理論上可能導致安全問題,如果 Go 應用程式用於驗證 IP 地址,然後將這些 IP 地址以其原始形式與將元件解釋為八進位制的非 Go 應用程式一起使用。通常建議在驗證後始終重新編碼值,這可以避免此類解析器不一致問題。

net/http

在客戶端或伺服器執行 TLS 握手時,net/http 包現在使用新的 (*tls.Conn).HandshakeContextRequest 上下文。

ServerReadTimeoutWriteTimeout 欄位設定為負值現在表示沒有超時,而不是立即超時。

ReadRequest 函式現在在請求有多個 Host 頭部時返回錯誤。

當重定向到 URL 的清除版本時,ServeMux 現在總是在 Location 頭部中使用相對 URL。以前它會回顯請求的完整 URL,如果客戶端可以被誘導傳送絕對請求 URL,這可能導致意外重定向。

在解釋 net/http 處理的某些 HTTP 頭部時,非 ASCII 字元現在將被忽略或拒絕。

如果 Request.ParseForm 在被 Request.ParseMultipartForm 呼叫時返回錯誤,後者現在在返回之前會繼續填充 Request.MultipartForm

net/http/httptest

ResponseRecorder.WriteHeader 現在會在提供的程式碼不是有效的三位數 HTTP 狀態碼時發生 panic。這與 net/http 包中的 ResponseWriter 實現的行為一致。

net/url

新的方法 Values.Has 報告是否設定了查詢引數。

os

File.WriteString 方法已最佳化,不再複製輸入字串。

reflect

新的 Value.CanConvert 方法報告值是否可以轉換為某種型別。這可以用於避免在切片太短時將切片轉換為陣列指標型別時發生 panic。以前,為此使用 Type.ConvertibleTo 就足夠了,但新允許的從切片到陣列指標型別的轉換即使型別可轉換也可能發生 panic。

新的 StructField.IsExportedMethod.IsExported 方法報告結構體欄位或型別方法是否已匯出。它們提供了檢查 PkgPath 是否為空的更易讀的替代方案。

新的 VisibleFields 函式返回結構體型別中所有可見欄位,包括匿名結構體成員中的欄位。

ArrayOf 函式在呼叫時帶有負長度引數時現在會發生 panic。

檢查 Type.ConvertibleTo 方法已不足以保證呼叫 Value.Convert 不會發生 panic。當將 `[]T` 轉換為 `*[N]T` 時,如果切片的長度小於 N,它可能會發生 panic。請參閱上面的語言更改部分。

Value.ConvertType.ConvertibleTo 方法已修復,不再將不同包中同名型別視為相同,以匹配語言允許的行為。

runtime/metrics

添加了新的度量指標,用於跟蹤已分配和已釋放的總位元組數和物件數。還添加了一個新的度量指標,用於跟蹤 goroutine 排程延遲的分佈。

runtime/pprof

塊剖析不再偏向於不常見的長事件而犧牲常見的短事件。

strconv

strconv 包現在使用 Ulf Adams 的 Ryū 演算法來格式化浮點數。該演算法在大多數輸入上提高了效能,在最壞情況輸入上速度提高了 99% 以上。

新的 QuotedPrefix 函式返回輸入開頭帶引號的字串(由 Unquote 理解)。

strings

Builder.WriteRune 方法現在為負的 rune 值寫入替換字元 U+FFFD,就像它對其他無效 rune 值所做的那樣。

sync/atomic

atomic.Value 現在具有 SwapCompareAndSwap 方法,這些方法提供了額外的原子操作。

syscall

GetQueuedCompletionStatusPostQueuedCompletionStatus 函式現在已棄用。這些函式簽名不正確,並被 golang.org/x/sys/windows 包中的等效函式取代。

在類 Unix 系統上,子程序的程序組現在在訊號被阻塞的情況下設定。這可以避免當父程序在後臺程序組中時向子程序傳送 SIGTTOU

SysProcAttr 的 Windows 版本有兩個新欄位。AdditionalInheritedHandles 是一個額外的控制代碼列表,將由新的子程序繼承。ParentProcess 允許指定新程序的父程序。

常量 MSG_CMSG_CLOEXEC 現在在 DragonFly 和所有 OpenBSD 系統上定義(它已經定義在某些 OpenBSD 系統和所有 FreeBSD、NetBSD 和 Linux 系統上)。

常量 SYS_WAIT6WEXITED 現在在 NetBSD 系統上定義(SYS_WAIT6 已經定義在 DragonFly 和 FreeBSD 系統上;WEXITED 已經定義在 Darwin、DragonFly、FreeBSD、Linux 和 Solaris 系統上)。

testing

添加了一個新的 測試標誌 -shuffle,用於控制測試和基準測試的執行順序。

新的 T.SetenvB.Setenv 方法支援在測試或基準測試期間設定環境變數。

text/template/parse

新的 SkipFuncCheck Mode 值更改模板解析器,使其不再驗證函式是否已定義。

time

Time 型別現在有一個 GoString 方法,當在 fmt 包中使用 %#v 格式說明符列印時,它將返回一個更有用的時間值。

新的 Time.IsDST 方法可用於檢查時間在其配置位置是否為夏令時。

新的 Time.UnixMilliTime.UnixMicro 方法分別返回自 1970 年 1 月 1 日 UTC 以來經過的毫秒數和微秒數。
新的 UnixMilliUnixMicro 函式返回與給定 Unix 時間對應的本地 Time

該包現在接受逗號“,”作為解析和格式化時間時小數秒的分隔符。例如,現在接受以下時間佈局

  • 2006-01-02 15:04:05,999999999 -0700 MST
  • Mon Jan _2 15:04:05,000000 2006
  • Monday, January 2 15:04:05,000 2006

新的常量 Layout 定義了參考時間。

unicode

IsIsGraphicIsLetterIsLowerIsMarkIsNumberIsPrintIsPunctIsSpaceIsSymbolIsUpper 函式現在對負的 rune 值返回 false,就像它們對其他無效的 rune 值所做的那樣。