Go 1.17 發行說明

Go 1.17 簡介

最新 Go 發行版 1.17 在 Go 1.16 發行六個月後推出。其變更大部分在於工具鏈、執行階段和函式庫的實作。與以往相同,此版本持續維持 Go 1 相容性承諾。我們預期絕大多數的 Go 程式都能像以往一樣繼續編譯和執行。

語言更動

Go 1.17 包含了三項小型的語言增強。

新增 unsafe 套件增強功能,簡化撰寫與 unsafe.Pointer安全性規則 相符的程式碼,但規則本身並未變更。更明確的說,使用 unsafe.Pointer 的既有程式碼仍舊有效,而新程式碼在使用 unsafe.Addunsafe.Slice 時仍必須遵循這些規則。

請注意,從切片轉換為陣列指標的新轉換是類型轉換第一次在執行階段出現錯誤的情況。假設類型轉換絕不會出現錯誤的分析工具應該更新,才能考量此可能性。

移植

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 以上版本相容,後者要求以 libc 進行非靜態 Go 二進位程式的系統呼叫。

ARM64

Go 程式現在會在各作業系統的 64 位元 ARM 架構上維護堆疊框架指標。以前,堆疊框架指標只會在 Linux、macOS 及 iOS 上啟用。

保留 loong64 GOARCH 值

主要 Go 編譯器尚未支援 LoongArch 架構,但我們已保留 GOARCH 值「loong64」。意即命名為 *_loong64.go 的 Go 檔案現在會在未使用該 GOARCH 值時被 Go 工具 忽略

工具

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 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

當在主模組以外安裝指令時,go get 會列印淘汰警告 (未加上 -d 旗標)。應改用 go install cmd@version 在特定版本下安裝指令,使用類似 @latest@v1.2.3 的字尾。在 Go 1.18 中,將永遠啟用 -d 旗標,而 go get 將僅用於變更 go.mod 中的相依性。

缺少 go 指令的 go.mod 檔案

如果主模組的 go.mod 檔案不包含 go 指令 (go) 而 go 指令無法更新 go.mod 檔案,go 指令現在會假設為 go 1.11,而不是目前版本。(自 Go 1.12 起,go mod init 已自動新增 go 指令。)

如果模組相依性沒有明確的 go.mod 檔案,或其 go.mod 檔案沒有包含 go 指令 (go),go 指令現在會假設相依性的 gogo 1.16,而不是目前的版本。(以 GOPATH 模式開發的相依性可能會缺少 go.mod 檔案,而 vendor/modules.txt 至今尚未記錄相依性 go.mod 檔案所指定的 go 版本。)

vendor 內容

如果主模組指定 `go` `1.17` 或更高版本,`go` `mod` `vendor` 現在使用各自的 `go.mod` 檔案中所標示的 `go` 版本,對 `vendor/modules.txt` 進行註解。在從供應來源碼建立模組套件時,會使用已註解的版本。

如果主模組指定 `go` `1.17` 或更高版本,`go` `mod` `vendor` 現在會略過供應相依項目的 `go.mod` 和 `go.sum` 檔案,否則,這些檔案可能會干擾 `go` 命令在 `vendor` 樹狀結構內呼叫時辨識正確模組根目錄的能力。

密碼提示

在使用 SSH 取得 Git 儲存庫時,`go` 命令現在預設會抑制 SSH 密碼提示和 Git Credential Manager 提示,如同先前對其他 Git 密碼提示所執行的一樣。使用密碼保護的 SSH 對私人 Git 儲存庫進行驗證的使用者可以設定一個 `ssh-agent`,讓 `go` 命令可以使用密碼保護的 SSH 金鑰。

go mod download

當在沒有引數的情況下呼叫 `go` mod download 時,它不再將已下載模組內容的雜湊值儲存在 `go.sum` 中。它仍可以對 `go.mod` 和 `go.sum` 進行載入建置清單所需的變更。這與 Go 1.15 中的行為相同。若要儲存所有模組的雜湊值,請使用 `go` mod download all

//go:build

`go` 命令現在了解 `//go:build` 行,並優先使用這些行,而不是 `// +build` 行。新的語法使用布林表達式,就像 Go 一樣,而且應該較不容易出錯。從此版本開始,新語法已獲得完全支援,而且所有 Go 檔案都應該更新為使用兩種具有相同意義的形式。為了協助移轉,gofmt 現在會自動同步兩種形式。如需語法和移轉計畫的更多詳細資訊,請參閱 https://go.dev.org.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://go.dev.org.tw/design/draft-gobuild

Vet

相符的 `//go:build` 和 `// +build` 行出現不符時,會出現新的警告

vet 工具現在會驗證 //go:build// +build 行是否位於檔案的正確部分,以及是否彼此同步。若非如此,gofmt 可用於修復這些行。如需詳細資訊,請參閱 https://go.dev.org.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 工具現在會針對具有與 errors 套件預期簽章不同的簽章,在實作 error 介面的型態上命名為 AsIsUnwrap 的方法發出警告。 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 函式。

來自執行時期的堆疊追蹤格式(在發生未捕捉的恐慌時,或在呼叫 runtime.Stack 時列印的堆疊追蹤格式)已獲得改善。之前,函式引數會根據記憶體配置以十六進位字元的格式列印。現在,原始碼中的每個引數會分別列印出來,並以逗點區隔。聚合類型(結構、陣列、字串、切片、介面和複雜型別)引數則以大括號分隔。有一個注意事項是,僅存在於暫存器中而未儲存在記憶體中的引數值可能是不正確的。函式傳回值(通常不正確)不再列印。

現在可以內嵌包含封閉函式的函式。此變更的其中一個影響為,含有封閉函式的函式可能會針對每個已內嵌函式的置放位置,產生不同的封閉函式程式碼指標。Go 函式值無法直接進行比較,但此變更可能會揭露使用 reflectunsafe.Pointer 繞過此語言限制並透過程式碼指標比對函式之程式碼中的錯誤。

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

標準函式庫

Cgo

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

URL 查詢語法分析

net/urlnet/http 套件過去除了「&符號」(&) 外,也會將「分號」(;) 作為 URL 查詢中的設定分隔符號。現在已拒絕採用未採用百分比編碼的分號設定,而且當要求 URL 中遇到分號時,net/http 伺服器會記錄警告至 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 警告。請注意,如果不同的系統以不同的方式來詮釋快取金鑰,那麼將分號作為查詢分隔符號可能會導致安全性問題。更多資訊請參閱 issue 25192

TLS 嚴格 ALPN

當設定 Config.NextProtos 時,現在伺服器會強制執行已設定通訊協定與客戶端宣告的 ALPN 通訊協定之間沒有重疊(如果有的話)。如果沒有相互支援的通訊協定,就會以 RFC 7301 規定的 no_application_protocol 警示來關閉連線。這有助於減輕 ALPACA 異通訊協定攻擊

但有例外,當伺服器的 Config.NextProtos 中包含值 "h2" 時,HTTP/1.1 客戶端可以連線,就像他們不支援 ALPN 一樣。更多資訊請參閱 issue 46310

對函式庫的次要變更

和往常一樣,根據 Go 1 相容性保證,針對函式庫進行了許多次要變更與更新。

archive/zip

新的方法 File.OpenRawWriter.CreateRawWriter.Copy 支援主要考量效能的情境。

bufio

Writer.WriteRune 方法現在會對負數字元值寫入替代字元 U+FFFD,就像處理其他無效數字元那樣。

bytes

Buffer.WriteRune 方法現在會對負數字元值寫入替代字元 U+FFFD,就像處理其他無效數字元那樣。

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 sysall,並在 Solaris、Illumos 和 DragonFlyBSD 上使用 getrandom syscall。

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

如果此欄位中的類型實作了 io.Closer 介面,DB.Close 方法目前會關閉 connector 欄位。

新的 NullInt16NullByte 結構代表可能為 null 的 int16 和 byte 值。這些值可以當作 Scan 方法的目的地,類似 NullString。

debug/elf

已新增 SHT_MIPS_ABIFLAGS 常數。

encoding/binary

binary.Uvarint 會在 10 個位元組之後停止讀取,以避免浪費運算。如果需要超過 10 個位元組,傳回的位元組數是 -11
在讀取錯誤編碼的 varint 時,以前的 Go 版本可能會傳回較大的負數數值。

encoding/csv

新的 Reader.FieldPos 方法會傳回與 Read 最近傳回的記錄中特定欄位開頭相應的行和欄。

encoding/xml

當註解出現在 Directive 中時,目前會用一個空白取代,而不是完全省略。

具備前導、後導或多個冒號的無效元素或屬性名稱目前會以未修改的形式存放至 Name.Local 欄位中。

flag

如果指定了無效的名稱,標記宣告現在會出現恐慌。

go/build

新的 Context.ToolTags 欄位包含符合目前 Go 工具鏈組態的建置標記。

go/format

SourceNode 函式現在會同步 //go:build 列和 // +build 列。如果檔案只有 // +build 列,它們會移至檔案中的適當位置,且會新增符合的 //go:build 列。否則, // +build 列會根據任何現有的 //go:build 列覆寫。如需進一步資訊,請參閱 https://go.dev.org.tw/design/draft-gobuild

go/parser

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

image

具體影像類型 (RGBAGray16 等) 現在會實作新的 RGBA64Image 介面。先前實作 draw.Image 的具體類型現在也會實作 draw.RGBA64Image,這是 image/draw 套件中的新介面。

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 類型的表格。

mime/multipart

Part.FileName 現在會對回傳值套用 filepath.Base。這可以減輕接受 multipart 訊息的應用程式中潛在的路徑穿越漏洞,例如會呼叫 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 位址隨後以其原始形式使用非 Go 應用程式(將元件詮釋為八進位),此類不匹配可能會假設地導致安全性問題。通常,建議在驗證後總是重新編碼值,這麼一來便能避免此類解析程式比對錯誤問題。

net/http

在用戶端或伺服器執行 TLS 握手時,net/http 套件現在會在 (*tls.Conn).HandshakeContext 中使用新的 Request 語境。

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

當要求具有多個 Host 標頭時,ReadRequest 函式現在會傳回錯誤。

在產生乾淨版本的 URL 轉址時,ServeMux 現在總會在 Location 標頭中使用相對 URL。在前述版本,它會回應要求的完整 URL,如果讓用戶端傳送絕對要求 URL,可能會導致意料之外的轉址。

net/http 所處理的特定 HTTP 標頭,非 ASCII 字元現在會被忽略或拒絕。

Request.ParseForm 在由 Request.ParseMultipartForm 呼叫時傳回錯誤,後者現在會繼續填入 Request.MultipartForm,然後傳回它。

net/http/httptest

當提供的程式碼不是有效的三位數 HTTP 狀態碼時,ResponseRecorder.WriteHeader 現在會崩潰。這符合 net/http 套件中 ResponseWriter 實作的行為。

net/url

新的方法 Values.Has 可報告查詢參數是否已設定。

os

File.WriteString 方法已經最佳化,不會拷貝輸入字串。

reflect

新的 Value.CanConvert 方法可報告值是否可轉換為類型。這可用於在將切片轉換為陣列指標類型(如果切片太短)時避免崩潰。先前,使用 Type.ConvertibleTo 已足以執行此動作,但新容許的切片轉換為陣列指標類型的轉換,即使這些類型是可以轉換的,也會導致崩潰。

新的 StructField.IsExportedMethod.IsExported 方法回報結構欄位或型別方法是否已匯出。它們提供一種可讀性更高的方式,可檢查 PkgPath 是否為空。

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

當呼叫 ArrayOf 函式並附帶負長度時,它現在會發生恐慌。

不再足夠僅檢查 Type.ConvertibleTo 方法,即可確保呼叫 Value.Convert 函式時不會發生恐慌。當嘗試將 `[]T` 轉換為 `*[N]T` 時,如果切片的長度小於 N 時,它可能會發生恐慌。請參閱上方 變更語言 的章節。

已修正 Value.ConvertType.ConvertibleTo 方法,它不會再將不同套件中具有相同名稱的型別視為相同,這符合語言所允許的規定。

runtime/metrics

已新增新的指標,用來追蹤總位元組數與配置和釋放的物件。還已新增新的指標,用來追蹤 goroutine 排程延遲的分布。

runtime/pprof

區塊剖析檔案不再偏向於較頻繁的長期事件,而非較頻繁的短期事件。

strconv

strconv 套件現在使用 Ulf Adams 的 Ryū 演算法來格式化浮點數。此演算法可提升大部分輸入項目的效能,且比最糟情況的輸入項目的速度快上 99% 以上。

新的 QuotedPrefix 函式傳回 `input` 開始處的引號字串(根據 Unquote 的定義)。

strings

Builder.WriteRune 方法現在會寫入替代字元 U+FFFD 予負號的符文值,就像它對其他無效符文所做的作業。

sync/atomic

atomic.Value 現在具有 SwapCompareAndSwap 方法,這提供了其他原子作業。

syscall

函式 GetQueuedCompletionStatusPostQueuedCompletionStatus 已過時。這些函式具有不正確的簽章,且已被 golang.org/x/sys/windows 套件中的等效函式所取代。

在類型的 Unix 系統,子程式的程序群組現在已設定封鎖訊號。如此一來可避免在父程式位於背景程序群組時,向子程式傳送 SIGTTOU

Windows 版本的 SysProcAttr 有兩個新的欄位。AdditionalInheritedHandles 是要由新子程式繼承的其他處理清單。ParentProcess 允許指定新程式的父程式。

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

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

測試

新增新的 測試旗標 -shuffle,用以控制測試和基準的執行順序。

新的 T.SetenvB.Setenv 方法支援設定環境變數,並在測試或基準期間持續發揮作用。

text/template/parse

新的 SkipFuncCheck Mode 值會變更範本剖析器,不再驗證函式是否已定義。

時間

Time 類型現在有 GoString 方法,在使用 fmt 套件中的 %#v 格式 специ符列印時間時,會傳回較實用的值。

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

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

套件現在接受逗號「,」做為剖析和格式化時間時的分數秒分隔符。例如,現在接受下列時間配置:

新常數 Layout 定義參考時間。

unicode

IsIsGraphicIsLetterIsLowerIsMarkIsNumberIsPrintIsPunctIsSpaceIsSymbolIsUpper 函式現在會對負符文值傳回 false,如同對其他無效符文所做的一樣。