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
amd64
和 386
已修正。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
-i
或 go
test
-i
,現在已不再必要:不使用 -i
時,建置的速度一樣快。詳情請參閱 go
help
cache
。
go
install
指令現在只會安裝命令列上直接列出的套件和指令。例如,go
install
cmd/gofmt
會安裝 gofmt 程式,但不會安裝它所依賴的任何套件。新的建置快取會讓未來的指令執行速度,即使已安裝依賴關係,也能和以前一樣快。若要強制安裝依賴項,請使用新的 go
install
-i
旗標。一般而言,安裝依賴項套件並不是必要的,而在未來的版本中,已安裝套件的概念可能會消失。
為了支援這些改善,go
build
實作的許多細節都已變更。這些變更暗示的一個新需求是,純二進位套件現在必須在其 stub 原始碼中宣告精確的 import 區塊,才能在使用純二進位套件連結程式時,讓這些 import 可用。詳情請參閱 go
help
filetype
。
測試
go
test
指令現在會快取測試結果:如果測試可執行檔和命令列與之前的執行相同,而且該執行所查詢的檔案和環境變數也未變更,go
test
會印出先前的測試輸出,並將經過時間置換為字串「(快取)」。測試快取僅適用於測試成功結果;僅適用於具有明確程式庫清單的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
輸出現在包含 PAUSE
和 CONT
狀態更新列,以標記 平行測試 暫停和繼續時的時間點。
新的 go
test
-failfast
旗標會在任何測試失敗後停用執行其他測試。請注意,與失敗測試平行執行的測試仍准予完成。
最後,新的 go
test
-json
旗標會透過新指令 go
tool
test2json
篩選測試輸出,以產生測試執行的機器可讀 JSON 格式描述。這允許在 IDE 和其他工具中建立豐富的測試執行簡報。
有關所有這些變更的更多詳細資料,請參閱 go
help
test
和 test2json 文件。
Cgo
現在會檢查由 cgo 使用 #cgo CFLAGS
指定的選項和類似選項,以符合允許的選項清單。這關閉了一個安全漏洞,已下載的套件會在建置其的機器上,使用 -fplugin
等編譯器選項來執行任意程式碼。這可能會導致建置錯誤,例如 invalid flag in #cgo CFLAGS
。有關更多背景資訊,以及如何處理此錯誤,請參閱 https://go.dev.org.tw/s/invalidflag。
Cgo 現在使用 Go 型別別名實作 C typedef,例如 “typedef
X
Y
”,以便 Go 程式碼可以互換地使用型別 C.X
和 C.Y
。它現在也支援使用無引數的函數式巨集。此外,文件已更新以澄清 Go 結構和 Go 陣列不受 cgo 匯出的函數型別簽章支援。
Cgo 現在支援直接從 C 存取 Go 字串值。C 前置宣告中的函數可能會使用型別 _GoString_
來接受 Go 字串做為引數。C 程式碼可能會呼叫 _GoStringLen
和 _GoStringPtr
,以便直接存取字串的內容。值型別 _GoString_
可能會傳入呼叫匯出的 Go 函數,而這個函數接收 Go 型別 string
的引數。
在工具鏈開機期間,環境變數 CC
和 CC_FOR_TARGET
分別指定產生的工具鏈將用於主機和目標建置的預設 C 編譯器。但是,如果工具鏈將與多個目標一起使用,可能有必要為每個目標指定不同的 C 編譯器(例如,darwin/arm64
不同於 linux/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),其中包含更新的網路介面。
Vet
go
vet
命令在檢查套件時現在總是能存取完整且最新的型別資訊,即使是在套件中使用 cgo 或供應商匯入的情況下也是如此。因此,報告應該會更準確。請注意,只有 go
vet
能夠存取此資訊;更底層的 go
tool
vet
無法存取此資訊,應避免使用,除非處理時在 vet
本身。 (在 Go 1.9 中,go
vet
提供存取與 go
tool
vet
相同所有旗標的權限)
診斷
此版本包括一個 可用的 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/ppc64le
、windows/386
和 windows/amd64
上運作;pie
現在可在 darwin/amd64
上運作,也會在所有系統上強制使用外部連結;plugin
現在可在 linux/ppc64le
和 darwin/amd64
上運作。
linux/ppc64le
埠現在需要將外部連結用於任何使用 cgo 的程式,甚至是標準函式庫的用法。
組譯器
對於 ARM 32 位元埠,組譯器現在支援 BFC
、BFI
、BFX
、BFXU
、FMULAD
、FMULAF
、FMULSD
、FMULSF
、FNMULAD
、FNMULAF
、FNMULSD
、FNMULSF
、MULAD
、MULAF
、MULSD
、MULSF
、NMULAD
、NMULAF
、NMULD
、NMULF
、NMULSD
、NMULSF
、XTAB
、XTABU
、XTAH
和 XTAHU
指令。
對於 ARM 64 位元埠,組譯器現在支援 VADD
、VADDP
、VADDV
、VAND
、VCMEQ
、VDUP
、VEOR
、VLD1
、VMOV
、VMOVI
、VMOVS
、VORR
、VREV32
和 VST1
指令。
位於 PowerPC 64 位元埠的組合語言組譯器現在支援 POWER9 指令 ADDEX
、CMPEQB
、COPY
、DARN
、LDMX
、MADDHD
、MADDHDU
、MADDLD
、MFVSRLD
、MTVSRDD
、MTVSRWS
、PASTECC
、VCMPNEZB
、VCMPNEZBCC
和 VMSUMUDM
。
位於 S390X 埠的組合語言組譯器現在支援 TMHH
、TMHL
、TMLH
和 TMLL
指令。
位於 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。
執行時期
對 LockOSThread
和 UnlockOSThread
進行巢狀呼叫時,其行為已改變。這些函式控制是否將一組常式鎖定到特定作業系統執行緒,好讓一組常式只在該執行緒上執行,而該執行緒只會執行那一組常式。之前,如果連續呼叫 LockOSThread
超過一次,等同於呼叫一次;而單次呼叫 UnlockOSThread
總是會解除對該執行緒的鎖定。現在,這些呼叫會巢狀:如果呼叫了多次 LockOSThread
,則必須呼叫相同次數的 UnlockOSThread
,才能解除對該執行緒的鎖定。絕不會巢狀呼叫這些函式的現有程式碼將維持正確無誤。而錯誤假設這些函式會巢狀的程式碼,則會變成正確無誤。在公開的 Go 程式碼中,大部分使用這些函式的範例都屬於第二類。
由於 LockOSThread
和 UnlockOSThread
的其中一個常見用法,是要允許 Go 程式碼可靠修改執行緒的局部狀態 (例如 Linux 或 Plan 9 名稱空間),因此執行時期現在將鎖定的執行緒視為不適合重用或用於建立新的執行緒。
堆疊追蹤不再包含隱含的包裝函式 (以前標示為 <autogenerated>
),除非故障或驚慌發生在包裝函式本身。因此,傳遞給諸如 Caller
等函式的跳過計數,現在應該總是與所寫程式碼的結構相符,而不是取決於最佳化決策和實作的詳細資料。
對垃圾回收器進行調整,以降低其對配置延遲期的影響。其運作時現使用較小比例的整體 CPU,但執行時間可能較長。垃圾回收器所用掉的總體 CPU 資源並未有明顯改變。
若未設定變數 $GOROOT
,GOROOT
功能現在採用在呼叫程式編譯當時的 GOROOT
或 GOROOT_FINAL
為預設值。先前為使用編譯呼叫程式之工具鏈編譯當時的 GOROOT
或 GOROOT_FINAL
。
取消對 GOMAXPROCS
設定值上限的限制。(在 Go 1.9 中,限制值為 1024。)
效能
一如既往地,這些變更多樣且廣泛,因此很難做出精準的效能聲明。大多數程式應會執行得稍快一點,原因在於垃圾回收器的加速、更好的產出程式碼,以及核心程式庫的最佳化。
垃圾回收器
當垃圾回收器處於活動狀態時,許多應用程式應會體驗到低上許多的配置延遲期與整體效能成本。
標準函式庫
標準函式庫的變更都算小。在 bytes
和 net/url
中的變更最有可能需要更新既有的程式。
函式庫的小變更
一如往常,對函式庫進行了種種小變更與更新,考量在 Go 1 下 相容性的承諾。
archive/tar
整體而言,特別標頭格式的處理獲得顯著的改善與擴充。
FileInfoHeader
向來會將其 os.FileInfo
引數(精確來說,是 FileInfo
的 Sys
方法所回傳的系統依賴資訊)中的 Unix UID 和 GID 編號記錄在回傳的 Header
裡。現在,它也會記錄與這些 ID 對應的使用者和群組名稱,以及裝置檔案的主要與次要裝置編號。
Header
的新欄位 Header.Format
型態為 Format
,控制 Writer
使用哪種 tar 標頭格式。預設值(一如往常)是選取可以編碼標頭所需欄位的支援度最高標頭類型(若可能,為 USTAR;否則若可能,為 PAX;否則,為 GNU)。Reader
會為它讀取的每個標頭設定 Header.Format
。
Reader
和 Writer
現在支援使用新的欄位 Header.PAXRecords
任意 PAX 記錄,這是既有 Xattrs
欄位的概化。
Reader
不再堅持 GNU 標頭中的檔案名稱或連結名稱必須為有效的 UTF-8。
寫入 PAX 或 GNU 格式的標頭時,Writer
現在包括已設定(若有)的 Header.AccessTime
和 Header.ChangeTime
欄位。寫入 PAX 格式的標頭時,這些時間包含毫秒以下的精度。
archive/zip
Go 1.10 支援更完整的時間和 ZIP 檔案中的字元集編碼。
原始 ZIP 格式使用標準 MS-DOS 編碼,將年、月、日、時、分和秒編碼成兩個 16 位元值的欄位。這種編碼無法表示時區或奇數秒,所以有多個擴充功能可以允許更豐富的編碼。在 Go 1.10 中,Reader
和 Writer
現在支援普遍理解的 Info-Zip 擴充功能,該擴充功能將時間以 32 位元 Unix 「自紀元以來秒數」的形式獨立編碼。FileHeader
的新 Modified
欄位為 time.Time
類型,淘汰了 ModifiedTime
和 ModifiedDate
欄位,這些欄位會繼續儲存 MS-DOS 編碼。Reader
和 Writer
現在採用常見慣例,即儲存時區無關 Unix 時間的 ZIP 檔案也會在 MS-DOS 欄位中儲存當地時間,這樣可以推算出時區偏移量。為了相容性,ModTime
和 SetModTime
方法的行為與較早版本相同;新的程式碼應該直接使用 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.Size
和 Writer.Size
方法回報 Reader
或 Writer
的基本緩衝區大小。
bytes
Fields
、FieldsFunc
、Split
和 SplitAfter
函數總是會傳回其輸入的子切片。Go 1.10 將每個傳回的子切片變更為容量等於其長度,以便附加到一個子切片不會覆寫原始輸入中的鄰接資料。
crypto/cipher
NewOFB
現在如果提供長度不正確的初始化向量,就會發生恐慌,一如封裝中的其他建構函數一直以來所發生的。(先前的行為是傳回一個 nil 的 Stream
實作。)
crypto/tls
使用 TLS 1.2 時,TLS 伺服器現在會宣告支援 SHA-512 簽章。伺服器早已支援 SHA-512 簽章,但一些用戶端只有在伺服器明確宣告支援時,才會選擇使用這些簽章。
crypto/x509
Certificate.Verify
現在會對憑證中包含的所有名稱強制執行名稱約束,而不僅僅是用戶端已詢問過的一個名稱。同理,現在會一次檢查所有已擴充的使用限制。因此,在驗證憑證後,現在可以完全信任憑證。不再需要為每個額外名稱或金鑰使用重新驗證憑證。
現在,已剖析的憑證也會報告 URI 名稱及 IP、電子郵件和 URI 約束,使用新的 Certificate
欄位 URIs
、PermittedIPRanges
、ExcludedIPRanges
、PermittedEmailAddresses
、ExcludedEmailAddresses
、PermittedURIDomains
和 ExcludedURIDomains
。現在會拒絕含有那些欄位無效值的憑證。
新的 MarshalPKCS1PublicKey
和 ParsePKCS1PublicKey
函數會將 RSA 公開金鑰轉換成 PKCS#1 編碼形式,也會將 PKCS#1 編碼形式轉換成 RSA 公開金鑰。
新的 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.Conn
而非每次使用sql.DB
只分析組態字串一次的驅動程式,或是想要存取每個sql.Conn
的基礎內容的驅動程式,可以讓其Driver
實作同時實作DriverContext
的新OpenConnector
方法。
實作ExecerContext
的驅動程式不再需要實作Execer
,類似地,實作QueryerContext
的驅動程式不再需要實作Queryer
。先前即使實作了基於內容的介面,除非也實作了非基於內容的介面,否則這些介面都會被忽略。
為允許驅動程式能更好分離使用快取驅動程式連線的相異客戶,如果Conn
實作新的SessionResetter
介面,則database/sql
現在會在重先使用Conn
進行新的客戶前呼叫ResetSession
。
debug/elf
此版本新增了 348 個新的重配置常數,分別分成重配置類型R_386
、R_AARCH64
、R_ARM
、R_PPC64
和R_X86_64
。
debug/macho
Go 1.10 新增支援,使用Section
結構的新Relocs
欄位,以及新的Reloc
、RelocTypeARM
、RelocTypeARM64
、RelocTypeGeneric
和RelocTypeX86_64
類型及關聯常數,從 Mach-O 區段讀取重配置。
Go 1.10 也新增支援LC_RPATH
載入命令,由RpathCmd
和Rpath
類型表示,以及新的命名常數,針對標頭中找到的各種旗標位元。
encoding/asn1
Marshal
現在正確編碼含有星號的字串,做為 UTF8String 類型而非 PrintableString,除非字串在結構欄位中,有標記強制使用 PrintableString。Marshal
現在也尊重新含有application
指令的結構標記。
新的 MarshalWithParams
函式會將其引數編組,就像附加的參數對應到其相關結構欄位的標籤一樣。
Unmarshal
現在會根據 explicit
和 tag
指令來符合結構欄位的標籤。
Marshal
和 Unmarshal
現在都支援新的結構欄位標籤 numeric
,用來表示 ASN.1 的 NumericString。
encoding/csv
Reader
現在禁止使用不合理的 Comma
和 Comment
設定,例如 NUL、換行符號、新行符號、無效符號和 Unicode 替換字元,或將 Comma
和 Comment
設定成彼此相等。
如果一個 CSV 記錄有語法錯誤且橫跨多個輸入行,ParseError
的新欄位 StartLine
,現在會回報記錄開始的行數。
encoding/hex
新函式 NewEncoder
和 NewDecoder
可提供用來從十六進制進行串流轉換的功能,類似 encoding/base32 和 encoding/base64 中已有的等效函式。
當 Decode
和 DecodeString
函式遇到格式錯誤的輸入時,現在會回傳已轉換的位元組數,以及錯誤訊息。以前在發生任何錯誤時,它們總是會回傳 0。
encoding/json
Decoder
新增一個新方法 DisallowUnknownFields
,可用來回報輸入含有不明 JSON 欄位時,發生解碼錯誤。(預設行為一直都是捨棄不明欄位。)
由於 修正了一個 reflect 錯誤 的緣故,Unmarshal
無法再解碼成內嵌在非公開結構型別的指標內的欄位,因為它無法初始化非公開的內嵌指標來指向新的儲存區。現在,Unmarshal
會在此情況下回傳一個錯誤。
encoding/pem
Encode
和 EncodeToMemory
在遇到無法編碼成 PEM 資料的區塊時,不再會產生部分輸出。
encoding/xml
新的函式 NewTokenDecoder
類似於 NewDecoder
,不過是用來建立一個從 TokenReader
進行讀取的解碼器,而不是從格式化為 XML 的位元組串流進行讀取。其目的是在讓客戶端函式庫中可以建立 XML 串流轉換器。
flag
預設的 Usage
函式現會將其第一行輸出列印至 CommandLine.Output()
,而非預設為 os.Stderr
,如此一來,當用戶使用 CommandLine.SetOutput
時,訊息才可正確重新導向。
PrintDefaults
現已在標誌使用字串的新行後適當地加入縮排,這樣多行式使用字串才能漂亮地顯示。
FlagSet
新增了 ErrorHandling
、Name
和 Output
等新方法,用來擷取傳遞給 NewFlagSet
和 FlagSet.SetOutput
的設定。
go/doc
為了支援上述的 doc 變更,可傳回 T
、*T
、**T
等切片的函式現會出現在 T
的 Type
的 Funcs
清單,而非出現在 Package
的 Funcs
清單。
go/importer
For
函式現接受非空值的查詢引數。
go/printer
上面 gofmt 區段 討論到 Go 原始碼預設格式化的變更已在 go/printer 套件中實作,也影響到更高等級的 go/format 套件的輸出。
hash
Hash
介面的實作現已建議實作 encoding.BinaryMarshaler
和 encoding.BinaryUnmarshaler
,以允許儲存和重新建立它們的內部狀態,而標準函式庫中的所有實作(hash/crc32、crypto/sha256 等)現已實作這些介面。
html/template
新的 Srcset
內容類型可在 img
標記的 srcset
屬性內適當地處理值。
math/big
Int
現在在 SetString
和 Text
方法中支援轉換為 2 到 62 進位制,並從這些進位制轉換。(之前只允許 2 到 36 進位制。)MaxBase
常數的值已更新。
Int
新增了一個 CmpAbs
新方法,這個方法就像 Cmp
,但只比對其引數的絕對值(而非符號)。
math/cmplx
複數的 Asin
、Asinh
、Atan
和 Sqrt
中的分支割線和其他邊界情況已修正,以符合 C99 標準中使用的定義。
math/rand
新的 Shuffle
函式和對應的 Rand.Shuffle
方法會將輸入順序洗牌。
math
新的函式 Round
和 RoundToEven
會將其引數四捨五入至最近的浮點整數值;Round
會將半整數四捨五入至較大的整數鄰近值(遠離 0),而 RoundToEven
會將半整數四捨五入至偶數整數鄰近值。
新的函式 Erfinv
和 Erfcinv
會計算反誤差函數與反互補誤差函數。
mime/multipart
Reader
現在接受檔案名稱屬性為空的區段。
mime
ParseMediaType
現在會略過無效屬性值;之前會回傳這些值作為空字串。
net
此套件中的 Conn
和 Listener
實作現在保證在 Close
回傳時,底層的檔案描述器已關閉。(在較早的版本中,如果 Close
停止其他 goroutine 中待處理的 I/O,檔案描述器可能會在 Close
回傳後不久,在其中一個 goroutine 中關閉。)
TCPListener
和 UnixListener
現在實作 syscall.Conn
,以便使用 syscall.RawConn.Control
設定底層檔案描述器的選項。
Pipe
回傳的 Conn
實作現在支援設定讀取和寫入截止時間。
IPConn.ReadMsgIP
、IPConn.WriteMsgIP
、UDPConn.ReadMsgUDP
和 UDPConn.WriteMsgUDP
方法現在已在 Windows 上實作。
net/http
在用戶端方面,現在可以透過 https://
URL 指定 HTTP 代理(通常由 ProxyFromEnvironment
設定),表示用戶端透過 HTTPS 連線到代理程式,再發出標準的代理 HTTP 要求。(之前,HTTP 代理 URL 必須以 http://
或 socks5://
開頭。)
在伺服器端,FileServer
及其單一檔案等效版本 ServeFile
會對 HEAD
要求套用 If-Range
檢查。FileServer
現在會將目錄讀取失敗訊息回報至 Server
的 ErrorLog
。此外,內容提供處理常式現在會在提供零長度內容時略過 Content-Type
標頭。
ResponseWriter
的 WriteHeader
方法現已廢棄,如果傳遞不合法的狀態碼 (非 3 碼),則會觸發恐慌。
當 Handler
未寫入任何輸出時,Server
將不再新增隱含的 Content-Type。
Redirect
現已在寫入 HTTP 回應之前設定 Content-Type
標頭。
net/mail
ParseAddress
和 ParseAddressList
現已支援各種過時的位址格式。
net/smtp
Client
新增一個 Noop
方法,以測試伺服器是否仍然回應。此外,它現在也能防範在輸入 Hello
和 Verify
方法時可能發生的 SMTP 注入攻擊。
net/textproto
ReadMIMEHeader
現已拒絕開頭是續行 (縮排) 標頭行的任何標頭。之前,具有縮排第一行的標頭被視作第一行未縮排。P>
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/page2
:path
之前的雙斜線錯誤地改寫成單一斜線,而 path
之後的雙斜線則正確保留。Go 1.10 保留兩個雙斜線,根據 RFC 3986 的要求,解析成 http://host//path//to/page2
。
此變更可能會中斷已存在的錯誤程式碼,其無意在路徑中建立開頭為雙斜線的基本 URL,並無意依賴 ResolveReference
來修正此錯誤。例如,若程式碼新增主機前綴,例如 http://host/
,至路徑,如 /my/api
,會產生一個 URL 包含雙斜線:http://host//my/api
。
UserInfo
的方法現在將 nil 接收器處理成等價於指向 zero UserInfo
的指標。之前,它們會觸發恐慌。
作業系統
File
新增方法 SetDeadline
、SetReadDeadline
和 SetWriteDeadline
,允許在底層檔案描述符支援非封鎖 I/O 作業時設定 I/O 截止時間。這些方法的定義與 net.Conn
中的定義相符。如果 I/O 方法因逾期而失敗,它將傳回逾時錯誤;新的 IsTimeout
函式回報錯誤是否代表逾時。
與 net.Conn
相符,File
的 Close
方法保證 Close
回傳後已關閉底層檔案描述符。(在之前的版本中,如果 Close
停止其他 goroutines 中的 I/O,檔案描述符的關閉可能會在 Close
回傳後不久的某個 goroutines 中發生)
在 BSD、macOS 和 Solaris 系統上,Chtimes
現在支援以奈秒精度設定檔案時間(假設底層檔案系統可以表示它們)。
反射
Copy
函式現在允許從字串複製到位元組陣列或位元組切片,以符合 內建 copy 函式。
在結構體中,嵌入指向未匯出的結構體類型的指標之前會不正確地回報一個空的 PkgPath
給對應的 StructField,結果是對於那些欄位, Value.CanSet
不正確地回傳 true,且 Value.Set
不正確地成功。底層的元資料已修正;對於那些欄位,CanSet
現在正確回傳 false,且 Set
現在正確地觸發恐慌。這可能會影響依反射為基礎的 unserlializer,在之前可以將資料 unserialize 到此類欄位但現在不行。例如,請參閱 encoding/json
筆記。
執行階段/剖析
如同 上面所述,封鎖和互斥鎖剖析現在包含符號資訊,因此無需不需要產生剖析的二進位檔即可檢視。
字串轉換
ParseUint
現在會回傳大小合適的最大數值整數以及任何 ErrRange
錯誤,正如它在文件中所記載的。之前它會回傳 0 和 ErrRange
錯誤。
字串
新的類型 Builder
可取代 bytes.Buffer
這個用例,將文字累積到 string
結果中。Builder
的 API 是 bytes.Buffer
的限制子集,能在 String
方法中安全避免資料重複複製。
syscall
在 Windows 上,新的 SysProcAttr
欄位 Token
,類型是 Token
,可在 StartProcess
期間 (因此在 os.StartProcess
和 exec.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 個新表情符號。