Go 1.10 釋出說明

Go 1.10 簡介

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

此版本改進了構建包的快取,增加了成功測試結果的快取在測試期間自動執行 vet,並允許使用 cgo 在 Go 和 C 之間直接傳遞字串值。一套新的硬編碼安全編譯器選項可能會在之前使用舊版本成功構建的程式碼中導致意外的invalid flag錯誤。

語言變化

語言規範沒有重大更改。

涉及無型別常量移位的邊界情況已得到澄清,因此編譯器已更新,允許索引表示式x[1.0 << s],其中s是無符號整數;go/types 包已實現此功能。

方法表示式的語法已更新,放寬了語法以允許任何型別表示式作為接收者;這與編譯器已經實現的相匹配。例如,struct{io.Reader}.Read是一個有效的(雖然不尋常的)方法表示式,編譯器已經接受,現在也得到了語言語法的允許。

移植

此版本沒有新增支援的作業系統或處理器架構。大部分工作都集中在加強對現有埠的支援,特別是彙編器中的新指令和編譯器生成的程式碼的改進。

Go 1.9 釋出說明中宣佈,Go 1.10 現在需要 FreeBSD 10.3 或更高版本;已刪除對 FreeBSD 9.3 的支援。

Go 現在又可以在 NetBSD 上執行,但需要未釋出的 NetBSD 8。只有 GOARCH amd64386 已修復。arm 埠仍然損壞。

在 32 位 MIPS 系統上,新的環境變數設定 GOMIPS=hardfloat (預設) 和 GOMIPS=softfloat 用於選擇浮點計算是使用硬體指令還是軟體模擬。

Go 1.10 是最後一個可以在 OpenBSD 6.0 上執行的版本。Go 1.11 將需要 OpenBSD 6.2。

Go 1.10 是最後一個可以在 OS X 10.8 Mountain Lion 或 OS X 10.9 Mavericks 上執行的版本。Go 1.11 將需要 OS X 10.10 Yosemite 或更高版本。

Go 1.10 是最後一個可以在 Windows XP 或 Windows Vista 上執行的版本。Go 1.11 將需要 Windows 7 或更高版本。

工具

預設 GOROOT & GOTMPDIR

如果環境變數 $GOROOT 未設定,go 工具以前會使用工具鏈編譯期間設定的預設 GOROOT。現在,在回退到該預設值之前,go 工具會嘗試從其自身的可執行路徑推斷 GOROOT。這允許二進位制分發包在檔案系統中的任何位置解壓,然後無需顯式設定 GOROOT 即可使用。

預設情況下,go 工具在系統臨時目錄中建立其臨時檔案和目錄(例如,Unix 上的 $TMPDIR)。如果設定了新的環境變數 $GOTMPDIR,go 工具將在該目錄中建立其臨時檔案和目錄。

構建和安裝

go build 命令現在僅根據原始檔內容、指定的構建標誌和編譯包中儲存的元資料來檢測過時的包。不再考慮或相關修改時間。過去為了在某種原因(例如,構建標誌更改)導致修改時間產生誤導時強制重新構建而新增 -a 的建議已不再必要:構建現在總是會檢測到何時必須重新構建包。(如果您發現並非如此,請提交錯誤報告。)

go build -asmflags-gcflags-gccgoflags-ldflags 選項現在預設只應用於命令列上直接列出的包。例如,go build -gcflags=-m mypkg 在構建 mypkg 時會將編譯器傳遞 -m 標誌,但不會傳遞給其依賴項。新的、更通用的形式 -asmflags=pattern=flags(其他類似)僅將 flags 應用於與模式匹配的包。例如:go install -ldflags=cmd/gofmt=-X=main.version=1.2.3 cmd/... 會安裝所有匹配 cmd/... 的命令,但只將 -X 選項應用於 cmd/gofmt 的連結器標誌。有關更多詳細資訊,請參閱 go help build

go build 命令現在維護一個最近構建包的快取,獨立於 $GOROOT/pkg$GOPATH/pkg 中已安裝的包。快取的效果應該是加快不顯式安裝包的構建,或者在不同原始碼副本之間切換時(例如,在版本控制系統中來回切換不同分支時)。過去為了加快速度而新增 -i 標誌的建議,例如 go build -igo test -i,已不再必要:沒有 -i 的構建執行速度同樣快。有關更多詳細資訊,請參閱 go help cache

go install 命令現在只安裝命令列上直接列出的包和命令。例如,go install cmd/gofmt 安裝 gofmt 程式,但不安裝它依賴的任何包。新的構建快取使未來的命令仍然像安裝了依賴項一樣快速執行。要強制安裝依賴項,請使用新的 go install -i 標誌。通常不需要安裝依賴包,並且已安裝包的概念在未來版本中可能會消失。

為了支援這些改進,go build 實現的許多細節都發生了變化。這些更改所隱含的一個新要求是,現在僅二進位制包必須在其存根原始碼中宣告準確的匯入塊,以便在使用僅二進位制包連結程式時可以提供這些匯入。有關更多詳細資訊,請參閱 go help filetype

Test

go test 命令現在會快取測試結果:如果測試可執行檔案和命令列與之前的執行匹配,並且該執行所查詢的檔案和環境變數也沒有改變,go test 將列印之前的測試輸出,並將耗時替換為字串“(cached)”。測試快取僅適用於成功的測試結果;僅適用於帶有明確包列表的 go test 命令;並且僅適用於使用 -cpu-list-parallel-run-short-v 測試標誌子集的命令列。繞過測試快取的慣用方法是使用 -count=1

go test 命令現在會自動對被測試的包執行 go vet,以在執行測試之前識別出重大問題。任何此類問題都將視為構建錯誤並阻止測試執行。此自動檢查只啟用可用 go vet 檢查中置信度高的一部分。要停用 go vet 的執行,請使用 go test -vet=off

go test -coverpkg 標誌現在將其引數解釋為與每個測試的依賴項匹配的逗號分隔模式列表,而不是要重新載入的包列表。例如,go test -coverpkg=all 現在是一種有意義的方式,可以為測試包及其所有依賴項啟用覆蓋率執行測試。此外,當執行多個測試時,現在支援 go test -coverprofile 選項。

如果因超時而失敗,測試現在更有可能在退出前寫入其配置檔案。

go test 命令現在總是將給定測試二進位制檔案執行的標準輸出和標準錯誤合併,並將兩者都寫入 go test 的標準輸出。在過去的版本中,go test 大部分時間才應用此合併。

go test -v 輸出現在包含 PAUSECONT 狀態更新行,用於標記並行測試何時暫停和繼續。

新的 go test -failfast 標誌在任何測試失敗後停用執行其他測試。請注意,允許與失敗測試並行執行的測試完成。

最後,新的 go test -json 標誌透過新的命令 go tool test2json 過濾測試輸出,以生成機器可讀的 JSON 格式的測試執行描述。這允許在 IDE 和其他工具中建立豐富的測試執行演示。

有關所有這些更改的更多詳細資訊,請參閱 go help testtest2json 文件

Cgo

cgo 使用 #cgo CFLAGS 等指定的選項現在會與允許選項列表進行檢查。這關閉了一個安全漏洞,在該漏洞中,下載的包使用諸如 -fplugin 之類的編譯器選項來在構建它的機器上執行任意程式碼。這可能導致構建錯誤,例如 invalid flag in #cgo CFLAGS。有關更多背景資訊以及如何處理此錯誤,請參閱 https://golang.com.tw/s/invalidflag

Cgo 現在使用 Go 類型別名實現 C typedef,如“typedef X Y”,這樣 Go 程式碼可以互換使用 C.XC.Y 型別。它現在還支援使用無引數函式式宏。此外,文件已更新,以澄清 cgo 匯出函式的型別簽名中不支援 Go 結構體和 Go 陣列。

Cgo 現在支援從 C 直接訪問 Go 字串值。C 前導碼中的函式可以使用 _GoString_ 型別來接受 Go 字串作為引數。C 程式碼可以呼叫 _GoStringLen_GoStringPtr 來直接訪問字串內容。型別為 _GoString_ 的值可以在呼叫接受 Go 型別 string 引數的匯出 Go 函式時傳遞。

在工具鏈引導期間,環境變數 CCCC_FOR_TARGET 分別指定生成工具鏈將用於主機和目標構建的預設 C 編譯器。但是,如果工具鏈將與多個目標一起使用,則可能需要為每個目標指定不同的 C 編譯器(例如,darwin/arm64linux/ppc64le 的不同編譯器)。新的環境變數集 CC_FOR_goos_goarch 允許為每個目標指定不同的預設 C 編譯器。請注意,這些變數僅在工具鏈引導期間適用,以設定生成工具鏈使用的預設值。隨後的 go build 命令使用 CC 環境變數或內建預設值。

Cgo 現在將某些通常對映到 Go 中指標型別的 C 型別轉換為 uintptr。這些型別包括 Darwin CoreFoundation 框架中的 CFTypeRef 層次結構和 Java JNI 介面中的 jobject 層次結構。

這些型別在 Go 側必須是 uintptr,否則會混淆 Go 垃圾回收器;它們有時並非真正的指標,而是編碼在指標大小整數中的資料結構。指向 Go 記憶體的指標不得儲存在這些 uintptr 值中。

由於此更改,受影響型別的值需要使用常量 0 進行零初始化,而不是常量 nil。Go 1.10 提供了 gofix 模組來幫助進行此重寫。

go tool fix -r cftype <pkg>
go tool fix -r jni <pkg>

有關更多詳細資訊,請參閱 cgo 文件

文件

go doc 工具現在將返回 T*T 切片的函式新增到型別 T 的顯示中,類似於現有返回單個 T*T 結果的函式的行為。例如:

$ go doc mail.Address
package mail // import "net/mail"

type Address struct {
    Name    string
    Address string
}
    Address represents a single mail address.

func ParseAddress(address string) (*Address, error)
func ParseAddressList(list string) ([]*Address, error)
func (a *Address) String() string
$

以前,ParseAddressList 只在包概述中顯示 (go doc mail)。

修復

go fix 工具現在會將 "golang.org/x/net/context" 的匯入替換為 "context"。(當使用 Go 1.9 或更高版本時,前者中的轉發別名使其與後者完全等效。)

獲取

go get 命令現在支援 Fossil 原始碼倉庫。

Pprof

runtime/pprof 包生成的阻塞和互斥鎖配置檔案現在包含符號資訊,因此可以在 go tool pprof 中檢視,而無需生成配置檔案的二進位制檔案。(所有其他配置檔案型別在 Go 1.9 中已更改為包含符號資訊。)

go tool pprof 配置檔案視覺化工具已從 github.com/google/pprof 更新到 git 版本 9e20b5b (2017-11-08),其中包括一個更新的 Web 介面。

Vet

go vet 命令現在在檢查包時總是能訪問到完整的、最新的型別資訊,即使對於使用 cgo 或 vendored 匯入的包也是如此。因此,報告應該更準確。請注意,只有 go vet 才能訪問此資訊;更底層的 go tool vet 沒有,除了在處理 vet 本身時應避免使用。(從 Go 1.9 開始,go vet 提供了與 go tool vet 相同的所有標誌的訪問許可權。)

Diagnostics

此版本包含一份新的可用 Go 程式診斷工具概述

Gofmt

Go 原始碼預設格式的兩個小細節已更改。首先,某些複雜的三索引切片表示式以前格式化為 x[i+1 : j:k],現在格式化為更一致的間距:x[i+1 : j : k]。其次,寫在一行上的單方法介面字面量(有時用於型別斷言)不再拆分為多行。

請注意,gofmt 的這類小更新會不時出現。一般來說,我們不建議構建檢查原始碼是否與特定版本 gofmt 輸出匹配的系統。例如,如果任何已簽入倉庫的程式碼“格式不正確”就失敗的持續整合測試本身就是脆弱的,不建議使用。

如果多個程式必須就用於格式化原始檔的 gofmt 版本達成一致,我們建議它們透過呼叫相同的 gofmt 二進位制檔案來實現這一點。例如,在 Go 開源倉庫中,我們的 Git 預提交鉤子是用 Go 編寫的,可以直接匯入 go/format,但它卻呼叫當前路徑中找到的 gofmt 二進位制檔案,這樣每次 gofmt 更改時,預提交鉤子就不需要重新編譯。

編譯器工具鏈

編譯器包含了許多對生成程式碼效能的改進,這些改進在支援的架構上分佈得相當均勻。

二進位制檔案中記錄的 DWARF 除錯資訊在以下幾個方面得到了改進:現在記錄了常量值;行號資訊更準確,使得程式的原始碼級別單步除錯效果更好;並且每個包現在都作為自己的 DWARF 編譯單元呈現。

各種構建模式已移植到更多系統。具體來說,c-shared 現在可以在 linux/ppc64lewindows/386windows/amd64 上工作;pie 現在可以在 darwin/amd64 上工作,並且在所有系統上強制使用外部連結;plugin 現在可以在 linux/ppc64ledarwin/amd64 上工作。

linux/ppc64le 埠現在要求所有使用 cgo 的程式(即使是標準庫使用的程式)都必須使用外部連結。

彙編器

對於 ARM 32 位埠,彙編器現在支援 BFCBFIBFXBFXUFMULADFMULAFFMULSDFMULSFFNMULADFNMULAFFNMULSDFNMULSFMULADMULAFMULSDMULSFNMULADNMULAFNMULDNMULFNMULSDNMULSFXTABXTABUXTAHXTAHU 指令。

對於 ARM 64 位埠,彙編器現在支援 VADDVADDPVADDVVANDVCMEQVDUPVEORVLD1VMOVVMOVIVMOVSVORRVREV32VST1 指令。

對於 PowerPC 64 位埠,彙編器現在支援 POWER9 指令 ADDEXCMPEQBCOPYDARNLDMXMADDHDMADDHDUMADDLDMFVSRLDMTVSRDDMTVSRWSPASTECCVCMPNEZBVCMPNEZBCCVMSUMUDM

對於 S390X 埠,彙編器現在支援 TMHHTMHLTMLHTMLL 指令。

對於 X86 64 位埠,彙編器現在支援 359 條新指令,包括完整的 AVX、AVX2、BMI、BMI2、F16C、FMA3、SSE2、SSE3、SSSE3、SSE4.1 和 SSE4.2 擴充套件集。彙編器也不再將 MOVL $0, AX 實現為 XORL 指令,以避免意外清除條件標誌。

Gccgo

由於 Go 的半年釋出計劃與 GCC 的年度釋出計劃保持一致,GCC 7 版本包含 Go 1.8.3 版本的 gccgo。我們預計下一個版本 GCC 8 將包含 Go 1.10 版本的 gccgo。

執行時

LockOSThreadUnlockOSThread 的巢狀呼叫行為已更改。這些函式控制 goroutine 是否鎖定到特定的作業系統執行緒,以便 goroutine 只在該執行緒上執行,並且該執行緒只執行該 goroutine。以前,連續多次呼叫 LockOSThread 等同於呼叫一次,並且單個 UnlockOSThread 總是解鎖執行緒。現在,呼叫是巢狀的:如果多次呼叫 LockOSThread,則必須呼叫相同次數的 UnlockOSThread 才能解鎖執行緒。現有程式碼如果小心不巢狀這些呼叫,將保持正確。現有程式碼如果錯誤地假設呼叫是巢狀的,將變得正確。公共 Go 原始碼中這些函式的大多數用法都屬於第二類。

由於 LockOSThreadUnlockOSThread 的一個常見用途是允許 Go 程式碼可靠地修改執行緒本地狀態(例如,Linux 或 Plan 9 名稱空間),因此執行時現在將鎖定的執行緒視為不適合重用或建立新執行緒。

除非在包裝器本身發生故障或恐慌,否則堆疊跟蹤不再包含隱式包裝器函式(以前標記為 <autogenerated>)。因此,傳遞給 Caller 等函式的跳過計數現在應該總是與所編寫程式碼的結構匹配,而不是依賴於最佳化決策和實現細節。

垃圾回收器已修改,以減少其對分配延遲的影響。它現在在執行時使用的總體 CPU 比例更小,但執行時間可能更長。垃圾回收器消耗的總 CPU 沒有顯著變化。

GOROOT 函式現在預設(當未設定 $GOROOT 環境變數時)為呼叫程式編譯時生效的 GOROOTGOROOT_FINAL。以前它使用編譯呼叫程式的工具鏈編譯時生效的 GOROOTGOROOT_FINAL

GOMAXPROCS 設定不再有限制。(在 Go 1.9 中,限制為 1024。)

效能

一如既往,這些變化是如此普遍和多樣,以至於很難對效能做出精確的說明。由於垃圾回收器的加速、更好的生成程式碼以及核心庫中的最佳化,大多數程式應該執行得更快一些。

垃圾收集器

當垃圾回收器處於活動狀態時,許多應用程式應該會經歷顯著更低的分配延遲和整體效能開銷。

標準庫

標準庫的所有更改都是微小的。bytesnet/url 中的更改最有可能需要更新現有程式。

對庫的微小更改

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

archive/tar

總的來說,對特殊頭部格式的處理得到了顯著的改進和擴充套件。

FileInfoHeader 始終將其 os.FileInfo 引數中的 Unix UID 和 GID 數字(特別是從 FileInfoSys 方法返回的系統相關資訊)記錄到返回的 Header 中。現在,它還記錄了與這些 ID 對應的使用者和組名,以及裝置檔案的主裝置號和次裝置號。

新的 Header.Format 欄位型別為 Format,控制 Writer 使用哪種 tar 頭部格式。預設情況下,與以前一樣,選擇最廣泛支援的頭部型別,該型別可以編碼頭部所需的欄位(如果可能,USTAR;否則,如果可能,PAX;否則,GNU)。Reader 為其讀取的每個頭部設定 Header.Format

ReaderWriter 現在支援任意 PAX 記錄,使用新的 Header.PAXRecords 欄位,這是現有 Xattrs 欄位的泛化。

Reader 不再堅持 GNU 頭部中的檔名或連結名必須是有效的 UTF-8。

在寫入 PAX 或 GNU 格式的頭部時,Writer 現在包含 Header.AccessTimeHeader.ChangeTime 欄位(如果設定)。在寫入 PAX 格式的頭部時,時間包括亞秒精度。

archive/zip

Go 1.10 為 ZIP 歸檔中的時間和字元集編碼添加了更完整的支援。

原始 ZIP 格式使用標準的 MS-DOS 編碼將年、月、日、時、分和秒編碼到兩個 16 位值中的欄位。該編碼不能表示時區或奇數秒,因此引入了多個擴充套件以允許更豐富的編碼。在 Go 1.10 中,ReaderWriter 現在支援廣泛理解的 Info-Zip 擴充套件,該擴充套件以 32 位 Unix“自紀元以來的秒數”形式單獨編碼時間。FileHeader 的新 Modified 欄位型別為 time.Time,它淘汰了 ModifiedTimeModifiedDate 欄位,這些欄位繼續儲存 MS-DOS 編碼。ReaderWriter 現在採用的常見約定是,儲存與時區無關的 Unix 時間的 ZIP 歸檔也以 MS-DOS 欄位儲存本地時間,以便可以推斷時區偏移。為了相容性,ModTimeSetModTime 方法的行為與早期版本相同;新程式碼應直接使用 Modified

ZIP 歸檔中每個檔案的頭部都有一個標誌位,指示名稱和註釋欄位是否編碼為 UTF-8,而不是系統特定的預設編碼。在 Go 1.8 及更早版本中,Writer 從不設定 UTF-8 位。在 Go 1.9 中,Writer 幾乎總是設定 UTF-8 位。這破壞了包含 Shift-JIS 檔名的 ZIP 歸檔的建立。在 Go 1.10 中,Writer 現在僅當名稱和註釋欄位都是有效的 UTF-8 且至少有一個是非 ASCII 時才設定 UTF-8 位。因為非 ASCII 編碼很少看起來像有效的 UTF-8,所以新的啟發式方法幾乎總是正確的。將 FileHeader 的新 NonUTF8 欄位設定為 true 會完全停用該檔案的啟發式方法。

Writer 現在還支援透過呼叫 Writer 的新 SetComment 方法來設定中央目錄結束記錄的註釋欄位。

bufio

新的 Reader.Sizebytes

FieldsFieldsFuncSplitSplitAfter 函式始終返回其輸入的子切片。Go 1.10 將每個返回的子切片的容量更改為與其長度相等,這樣追加到一個子切片就不會覆蓋原始輸入中相鄰的資料。

crypto/cipher

NewOFB 現在會在給定初始化向量長度不正確時發生 panic,就像該包中的其他建構函式一直以來那樣。(以前它返回一個 nil Stream 實現。)

crypto/tls

TLS 伺服器現在在使用 TLS 1.2 時宣稱支援 SHA-512 簽名。伺服器已經支援這些簽名,但有些客戶端除非明確宣稱,否則不會選擇它們。

crypto/x509

Certificate.Verify 現在會強制執行證書中所有名稱的名稱約束,而不僅僅是客戶端查詢的單個名稱。擴充套件金鑰用法限制也同樣一次性檢查。因此,證書驗證後,現在可以完全信任它。不再需要為每個附加名稱或金鑰用法重新驗證證書。

已解析的證書現在還使用新的 Certificate 欄位 URIsPermittedIPRangesExcludedIPRangesPermittedEmailAddressesExcludedEmailAddressesPermittedURIDomainsExcludedURIDomains 報告 URI 名稱以及 IP、電子郵件和 URI 約束。具有這些欄位無效值的證書現在將被拒絕。

新的 MarshalPKCS1PublicKeyParsePKCS1PublicKey 函式將 RSA 公鑰轉換為 PKCS#1 編碼形式並從 PKCS#1 編碼形式轉換。

新的 MarshalPKCS8PrivateKey 函式將私鑰轉換為 PKCS#8 編碼形式。(ParsePKCS8PrivateKey 自 Go 1 起就已存在。)

crypto/x509/pkix

Name 現在實現了一個 String 方法,該方法以標準 RFC 2253 格式格式化 X.509 區分名稱。

database/sql/driver

當前保留由 driver.Rows.Next 提供的目標緩衝區的驅動程式應確保它們不再在該呼叫之外寫入分配給目標陣列的緩衝區。驅動程式必須小心,在關閉 driver.Rows 時,底層緩衝區不會被修改。

希望為客戶端構建 sql.DB 的驅動程式現在可以實現 Connector 介面並呼叫新的 sql.OpenDB 函式,而不再需要將所有配置編碼到傳遞給 sql.Open 的字串中。

希望僅為每個 sql.DB 而不是每個 sql.Conn 解析一次配置字串,或者希望訪問每個 sql.Conn 的底層上下文的驅動程式,可以使其 Driver 實現也實現 DriverContext 的新 OpenConnector 方法。

實現 ExecerContext 的驅動程式不再需要實現 Execer;類似地,實現 QueryerContext 的驅動程式不再需要實現 Conn 實現了新的 SessionResetter 介面,則 database/sql 現在將在為新客戶端重用 Conn 之前呼叫 ResetSession

debug/elf

此版本在重定位型別 R_386R_AARCH64R_ARMR_PPC64R_X86_64 之間添加了 348 個新的重定位常量。

debug/macho

Go 1.10 添加了對從 Mach-O 段讀取重定位的支援,使用 Section 結構體的新 Relocs 欄位以及新的 RelocRelocTypeARMRelocTypeARM64RelocTypeGenericRelocTypeX86_64 型別以及相關常量。

Go 1.10 還添加了對 LC_RPATH 載入命令的支援,由型別 RpathCmdRpath 表示,以及用於頭部中各種標誌位的新命名常量

encoding/asn1

Marshal 現在正確地將包含星號的字串編碼為 UTF8String 型別,而不是 PrintableString,除非該字串在帶有強制使用 PrintableString 標籤的結構體欄位中。Marshal 現在也遵守包含 application 指令的結構體標籤。

新的 MarshalWithParams 函式會將其引數封送,就像額外的引數是其關聯的結構體欄位標籤一樣。

Unmarshal 現在遵守使用 explicittag 指令的結構體欄位標籤。

MarshalUnmarshal 現在都支援一個新的結構體欄位標籤 numeric,表示 ASN.1 NumericString。

encoding/csv

Reader 現在不允許使用無意義的 CommaComment 設定,例如 NUL、回車、換行、無效符文和 Unicode 替換字元,或者將 CommaComment 設定為彼此相等。

在 CSV 記錄跨越多行輸入且出現語法錯誤的情況下,Reader 現在會在 ParseError 的新 StartLine 欄位中報告記錄開始的行號。

encoding/hex

新的函式 NewEncoderNewDecoder 提供流式十六進位制轉換,類似於 encoding/base32encoding/base64 中已有的等效函式。

DecodeDecodeString 函式遇到格式錯誤的輸入時,它們現在會返回已轉換的位元組數以及錯誤。以前,它們總是返回 0 與任何錯誤。

encoding/json

Decoder 添加了一個新方法 DisallowUnknownFields,它會導致在解碼時將帶有未知 JSON 欄位的輸入報告為解碼錯誤。(預設行為始終是丟棄未知欄位。)

由於修復了一個反射 bugUnmarshal 不再能夠解碼到嵌入式指向未匯出結構體型別的指標中的欄位,因為它無法初始化未匯出的嵌入式指標以指向新儲存。在這種情況下,Unmarshal 現在會返回一個錯誤。

encoding/pem

當遇到無法編碼為 PEM 資料的塊時,EncodeEncodeToMemory 不再生成部分輸出。

encoding/xml

新的函式 NewTokenDecoder 類似於 NewDecoder,但它建立的解碼器從 TokenReader 讀取,而不是從 XML 格式的位元組流讀取。這旨在使客戶端庫能夠構建 XML 流轉換器。

flag

預設的 Usage 函式現在將其輸出的第一行列印到 CommandLine.Output(),而不是假設 os.Stderr,以便使用 CommandLine.SetOutput 的客戶端可以正確重定向用法訊息。

PrintDefaults 現在會在標誌用法字串中的換行符後新增適當的縮排,以便多行用法字串顯示得更好。

FlagSet 添加了新方法 ErrorHandlingNameOutput,以檢索傳遞給 NewFlagSetFlagSet.SetOutput 的設定。

go/doc

為了支援上面描述的文件更改,返回 T*T**T 等切片的函式現在在 TTypeFuncs 列表中報告,而不是在 PackageFuncs 列表中。

go/importer

For 函式現在接受非 nil 的查詢引數。

go/printer

上面gofmt 部分討論的 Go 原始碼預設格式的更改已在 go/printer 包中實現,並且也影響了更高級別的 go/format 包的輸出。

hash

現在鼓勵 Hash 介面的實現也實現 encoding.BinaryMarshalerencoding.BinaryUnmarshaler,以允許儲存和重新建立其內部狀態,並且標準庫中的所有實現(hash/crc32crypto/sha256 等)現在都實現了這些介面。

html/template

新的 Srcset 內容型別允許正確處理 img 標籤的 srcset 屬性中的值。

math/big

Int 現在支援在其 SetStringText 方法中進行 2 到 62 進位制的轉換。(以前它只允許 2 到 36 進位制。)常量 MaxBase 的值已更新。

Int 添加了一個新的 CmpAbs 方法,該方法類似於 Cmp,但只比較其引數的絕對值(不比較符號)。

Float 添加了一個新的 Sqrt 方法來計算平方根。

math/cmplx

AsinAsinhAtanSqrt 中的分支切割和其他邊界情況已更正,以符合 C99 標準中使用的定義。

math/rand

新的 Shuffle 函式和相應的 Rand.Shuffle 方法打亂輸入序列。

math

新的函式 RoundRoundToEven 將其引數四捨五入到最接近的浮點整數;Round 將半整數四捨五入到其較大的整數鄰居(遠離零),而 RoundToEven 將半整數四捨五入到其偶數整數鄰居。

新的函式 ErfinvErfcinv 計算逆誤差函式和逆補誤差函式。

mime/multipart

Reader 現在接受檔名屬性為空的部分。

mime

ParseMediaType 現在會丟棄無效的屬性值;以前它會將這些值作為空字串返回。

net

此包中的 ConnListener 實現現在保證當 Close 返回時,底層檔案描述符已關閉。(在早期版本中,如果 Close 停止了其他 goroutine 中的掛起 I/O,則檔案描述符的關閉可能會在 Close 返回後不久在這些 goroutine 中的一箇中發生。)

TCPListenerUnixListener 現在實現 syscall.Conn,以允許使用 syscall.RawConn.Control 在底層檔案描述符上設定選項。

Pipe 返回的 Conn 實現現在支援設定讀寫截止時間。

IPConn.ReadMsgIPIPConn.WriteMsgIPUDPConn.ReadMsgUDPUDPConn.WriteMsgUDP 方法現在已在 Windows 上實現。

net/http

在客戶端,HTTP 代理(最常見的是透過 ProxyFromEnvironment 配置的)現在可以指定為 https:// URL,這意味著客戶端透過 HTTPS 連線到代理,然後發出標準的代理 HTTP 請求。(以前,HTTP 代理 URL 必須以 http://socks5:// 開頭。)

在伺服器端,FileServer 及其單檔案等效項 ServeFile 現在將 If-Range 檢查應用於 HEAD 請求。FileServer 現在還將目錄讀取失敗報告給 ServerErrorLog。內容服務處理程式在服務零長度內容時也會省略 Content-Type 頭部。

ResponseWriterWriteHeader 方法現在在傳遞無效(非 3 位數)狀態碼時會發生 panic。

Handler 不寫入任何輸出時,Server 將不再新增隱式 Content-Type。

Redirect 現在在寫入 HTTP 響應之前設定 Content-Type 頭部。

net/mail

ParseAddressParseAddressList 現在支援各種過時的地址格式。

net/smtp

Client 添加了一個新的 Noop 方法,用於測試伺服器是否仍在響應。它現在還會防範在 HelloVerify 方法的輸入中可能出現的 SMTP 注入。

net/textproto

ReadMIMEHeader 現在拒絕以續行(縮排)頭部行開頭的任何頭部。以前,以縮排第一行開頭的頭部被視為第一行未縮排。

net/url

ResolveReference 現在保留目標 URL 中多個前導斜槓。以前它將多個前導斜槓重寫為單個斜槓,導致 http.Client 錯誤地跟蹤某些重定向。

例如,此程式碼的輸出已更改:

base, _ := url.Parse("http://host//path//to/page1")
target, _ := url.Parse("page2")
fmt.Println(base.ResolveReference(target))

注意 path 周圍的雙斜槓。在 Go 1.9 及更早版本中,解析後的 URL 是 http://host/path//to/page2path 之前的雙斜槓被錯誤地重寫為單個斜槓,而 path 之後的雙斜槓被正確保留。Go 1.10 保留了兩個雙斜槓,解析為 http://host//path//to/page2,正如 RFC 3986 所要求的。

此更改可能會破壞現有有缺陷的程式,這些程式無意中構建了在路徑中具有前導雙斜槓的基 URL,並且無意中依賴 ResolveReference 來糾正該錯誤。例如,如果程式碼將 http://host/ 等主機字首新增到 /my/api 等路徑,則可能發生這種情況,從而導致 URL 出現雙斜槓:http://host//my/api

UserInfo 的方法現在將 nil 接收器視為等同於指向零值 UserInfo 的指標。以前,它們會發生 panic。

os

File 添加了新方法 SetDeadlineSetReadDeadlineSetWriteDeadline,允許在底層檔案描述符支援非阻塞 I/O 操作時設定 I/O 截止時間。這些方法的定義與 net.Conn 中的定義匹配。如果 I/O 方法因錯過截止時間而失敗,它將返回超時錯誤;新的 IsTimeout 函式報告錯誤是否表示超時。

同樣與 net.Conn 匹配,FileClose 方法現在保證當 Close 返回時,底層檔案描述符已關閉。(在早期版本中,如果 Close 停止了其他 goroutine 中的掛起 I/O,則檔案描述符的關閉可能會在 Close 返回後不久在這些 goroutine 中的一箇中發生。)

在 BSD、macOS 和 Solaris 系統上,Chtimes 現在支援以納秒精度設定檔案時間(假設底層檔案系統可以表示它們)。

reflect

Copy 函式現在允許從字串複製到位元組陣列或位元組切片,以匹配內建的 copy 函式

在結構體中,嵌入的指向未匯出結構體型別的指標以前在相應的 StructField 中錯誤地報告為空 PkgPath,導致這些欄位的 Value.CanSet 錯誤地返回 true,並且 Value.Set 錯誤地成功。底層元資料已更正;對於這些欄位,CanSet 現在正確返回 false,Set 現在正確地 panic。這可能會影響以前可以解組到此類欄位但現在不能的基於反射的解組器。例如,請參閱 encoding/json 註釋

runtime/pprof

上所述,阻塞和互斥鎖配置檔案現在包含符號資訊,因此可以在無需生成它們的二進位制檔案的情況下檢視它們。

strconv

ParseUint 現在會與任何 ErrRange 錯誤一起返回適當大小的最大幅值整數,正如其文件所述。以前它會與 ErrRange 錯誤一起返回 0。

strings

一種新型別 Builder 取代了 bytes.Buffer 用於將文字累積到 string 結果的用例。Builder 的 API 是 bytes.Buffer 的一個受限子集,它允許在 String 方法期間安全地避免建立資料的重複副本。

syscall

在 Windows 上,新的 SysProcAttr 欄位 Token,型別為 Token,允許在 StartProcess 期間(因此也在 os.StartProcessexec.Cmd.Start 期間)建立以其他使用者身份執行的程序。新的函式 CreateProcessAsUser 提供了對底層系統呼叫的訪問。

在 BSD、macOS 和 Solaris 系統上,現在實現了 UtimesNano

time

LoadLocation 現在會先使用 $ZONEINFO 環境變數指定的目錄或未壓縮的 zip 檔案,然後再查詢已知安裝位置的預設系統特定列表或 $GOROOT/lib/time/zoneinfo.zip

新的函式 LoadLocationFromTZData 允許將 IANA 時區檔案資料轉換為 Location

unicode

unicode 包和整個系統相關的支援已從 Unicode 9.0 升級到 Unicode 10.0,增加了 8,518 個新字元,包括四個新指令碼、一個新屬性、一個比特幣貨幣符號和 56 個新表情符號。