go 1.18 系列(1)- 變化說明

go 1.18 系列(1)- 變化說明

go 1.18正式發佈了,這個版本比較重要,所以需要詳細指導這個版本改了些什麼。

第一篇是對發佈的文檔進行了學習,後續會針對比較重要的部分進行詳細分析和學習。包括:

  1. 泛型
  2. 模糊測試
  3. 工作空間

go 1.18 doc

Go 1.18 正式發佈了!支持泛型、性能優化

語法規範

對語言、工具鏈的實現、運行時和庫的更改,對GO 1兼容。

泛型

go1.18 最明顯也是最重要的就是泛型,這個新語言有大量未在生產環境中進行測試的新代碼,生產環境中部署泛型代碼時請謹慎行事

以下是最明顯變化的列表

  • 函數類型聲明 的語法,現在接受**類型參數**
  • 參數化函數和類型可以通過在它們後面加上方括號中的類型參數列表來實例化
  • 新標記~已添加到一組 操作符和標點符號
  • 接口類型的語法現在允許嵌入任意類型(不僅僅是接口的類型名稱)以及 union 和 ~T 類型元素。,這樣的接口只能用作類型約束。
  • 新的 預聲明標識符 any是空接口的別名。它可以用來代替 interface{}.
  • 新的 預聲明標識符 comparable是一個接口,表示可以使用==or比較的所有類型的集合!=。它只能用作(或嵌入)類型約束。

有三個使用泛型的實驗包可能有用。這些包在 x/exp 存儲庫中;他們的 API 不在 Go 1 保證範圍內

  • golang.org/x/exp/constraints:對通用代碼有用的約束,例如 constraints.Ordered.
  • golang.org/x/exp/slices:對任何元素類型的切片進行操作的通用函數集合。
  • golang.org/x/exp/maps:對任何鍵或元素類型的映射進行操作的通用函數集合。

當前的泛型實現具有以下已知限制:

  • Go 編譯器無法處理泛型函數或方法中的類型聲明,計劃在 Go 1.19 中取消這個限制。
  • Go 編譯器不接受具有預聲明函數 real、imag 和 complex 的參數類型的參數,計劃在 Go 1.19 中取消這個限制。
  • 如果 m 由 P 的約束接口顯式聲明,Go 編譯器僅支持在類型參數類型 P 的值 x 上調用方法 m。 類似地,方法值 x.m 和方法表達式 P.m 也僅在 m 由 P 顯式聲明時才受支持,即使 m 可能在 P 的方法集中,因爲 P 中的所有類型都實現了 m,計劃在 Go 1.19 中取消這個限制。
  • Go 編譯器不支持訪問結構字段 x.f,其中 x 是類型參數類型,即使類型參數的類型集中的所有類型都具有字段 f,計劃在 Go 1.19 中取消這個限制。
  • 不允許將類型參數或指向類型參數的指針作爲結構類型中的未命名字段嵌入,同樣地,也不允許在接口類型中嵌入類型參數。
  • 具有多個 term 的 union 元素可能不包含具有非空方法集的接口類型。

理解

怎麼理解上面這囉嗦的東西呢。

函數: 定義中添加了 [ TypeParameters ]

FunctionDecl = "func" FunctionName [ TypeParameters ] Signature [ FunctionBody ] .
FunctionName = identifier .
FunctionBody = Block .

如果函數聲明指定類型參數,則函數名稱表示泛型函數。泛型函數必須先被實例化,然後才能被調用或用作值。

func min[T ~int|~float64](x, y T) T {
	if x < y {
		return x
	}
	return y
}

也就是說這個T必須指定類型,先實例化爲接受底層使用int和float64兩種類型的類型,這樣這個函數就是一個泛型函數。

類型聲明:

TypeDef = identifier [ TypeParameters ] Type .

例子:任意類型的Tree

type Tree[T any] struct {
	left, right *Tree[T]
	value       T
}

現在上面這兩種都接受類型參數 [ TypeParameters ]

參數化函數和類型實例化

說的是如1中,T實例化爲接受基類型是int和float64的類型,參數x,y的類型也是這個。

~ 符號

type Float interface {
	~float32 | ~float64
}

type MyFloat float64

f := min(MyFloat(1), MyFloat(2))

現在MyFloat雖然是自己定義的, 但是基礎類型是float64,就可以將這個類型傳入min函數中使用。

func min[T int|float64](x, y T) T {
	// ...
}

如果Float定義中沒有使用~, 那麼MyFloat就不能傳入min函數使用,編譯器會任務他們不是一個類型

接口類型

定義中添加了

InterfaceType  = "interface" "{" { InterfaceElem ";" } "}" .
InterfaceElem  = MethodElem | TypeElem .
MethodElem     = MethodName Signature .
MethodName     = identifier .
TypeElem       = TypeTerm { "|" TypeTerm } .
TypeTerm       = Type | UnderlyingType .
UnderlyingType = "~" Type .

例子:

type Float interface {
	~float32 | ~float64
}

這樣這個接口Float就變成了一個約束。 可以使用 | 分割的Type分割,也可以添加~變爲基類型。

any

// any is an alias for interface{} and is equivalent to interface{} in all ways.
type any = interface{}

any 就是一個接口,按我的理解是在泛型使用接口就用any, 其他原有還是使用interface{}, 不然原有低版本情況就會出一些問題,當然仁者見仁了。

切換到Go 1.18後的第一件事:將interface{}全部替換爲any

comparable

// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable interface{ comparable }

也是一個接口,但是這個接口只能用在 ==!= 這種比較類型,作爲這種類型約束

3個約束包

這三個就是官方暫時使用的類型約束,後續應該會添加到源碼裏。

這裏就定義了很多基類型,這樣可以方便使用。在寫代碼的時候記得用就好,別什麼都自己又定義一遍。

工具

模糊測試

Go 1.18 包括 fuzzing(模糊測試) 的實現,如 fuzzing 提案 所述,詳情請參閱 fuzzing 教程 以開始使用。

這部分詳細內容會在第三篇文章中進行學習和總結

注意,模糊測試會消耗大量內存,並且可能會影響機器運行時的性能。

另請注意,模糊引擎在運行時會將擴展測試覆蓋率的值寫入模糊緩存目錄 $GOCACHE/fuzz。目前對可以寫入模糊緩存的文件數量或總字節數沒有限制,因此可能會佔用大量存儲空間(可能爲 GB 級別)。

bug修復

  1. Go 1.18 編譯器現在可以正確報告declared but not used在函數文字中設置但從未使用過的變量的錯誤
  2. Go 1.18 編譯器現在在將如 '1' << 32 之類的符文常量表達式作爲參數傳遞給預聲明函數 print 和 println 時會報告溢出。

修改都很簡單,使用 go vet 然後修改成正確的就好了。

Ports

AMD64

Go 1.18 引入了新的GOAMD64環境變量,它在編譯時選擇 AMD64 架構的最低目標版本,允許的值爲v1、 v2、v3或v4,默認是v1。

RISC-V

Linux 上的 64 位 RISC-V 架構(linux/riscv64 端口)現在支持 c-archive 和 c-shared 構建模式。

Linux (這個注意一下老系統)

Go 1.18 需要 Linux 內核版本 2.6.32 或更高版本。

Windows

windows/arm 和 windows/arm64 端在支持非合作搶佔,有希望解決在調用 Win32 函數時遇到的一些細微的 bug,這些bug在很長一段時間內會阻塞。

iOS

在 iOS(ios/arm64 端口)和在基於 AMD64 的 macOS(ios/amd64 端口)上運行的 iOS 模擬器上,Go 1.18 現在需要 iOS 12 或更高版本; 已停止支持以前的版本。

FreeBSD

Go 1.18 是支持 FreeBSD 11.x 的最後一個版本,Go 1.19 需要 FreeBSD 12.2+ 或 FreeBSD 13.0+。

性能提升

由於 Go1.17 中寄存器 ABI 調用約定擴展到了 RM64 / Apple M1 / PowerPC 64 架構,因此 Go1.18 對這幾個架構包含了高達 20% 的 CPU 性能提升。

執行命令

go get

go get 現在致力於調整go.mod. 實際上,該 -d標誌始終處於啓用狀態。要在當前模塊的上下文之外安裝最新版本的可執行文件, 請使用 go install example.com/cmd@latest. 可以使用任何 版本查詢 來代替latest. go get現在在module外使用時會報告錯誤,因爲沒有go.mod要更新的文件, 在 GOPATH 模式下(帶有 GO111MODULE=off),go get仍然像以前一樣構建和安裝包。

自動go.mod和go.sum更新

go mod graph, go mod vendor, go mod verify, 不在自動更新 go.mod 和 go.sum go get, go mod tidy, go mod download 這三個命令纔會更新

go version

此外,該go命令嵌入了有關構建的信息,包括構建和工具標籤(用 設置-tags)、編譯器、彙編器和鏈接器標誌(-gcflags如CGO_CFLAGS)。 VCS 和構建信息都可以使用 go version -m file或 runtime/debug.ReadBuildInfo(對於當前運行的二進制文件)或新debug/buildinfo 包與模塊信息一起讀取。

要從使用go1.18 構建的二進制文件中讀取版本信息,請使用1.18+ 中的go version命令和 debug/buildinfo包。go

go mod download

go.mod文件指定go 1.17 或更高,go mod download現在不帶參數只下載主模塊文件中明確需要go.mod的模塊的源代碼。 要下載傳遞依賴項的源代碼,請使用 go mod download all.

go mod vendor

該go mod vendor子命令現在支持-o設置輸出目錄的標誌。(其他go命令vendor在加載包時仍然從模塊根目錄讀取-mod=vendor)

go mod tidy

該go mod tidy命令現在在文件中爲模塊保留了額外的校驗和,這些go.sum模塊需要源代碼來驗證每個導入的包是否僅由構建列表中的一個模塊提供

go work (工作區這個單獨會寫)

該go命令現在支持“工作區”模式。如果 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現在刪除了 模塊聲明或稍後在其文件 中的現已過時的// +build行

Gofmt

gofmt現在同時讀取和格式化輸入文件,GOMAXPROCS進行內存限制. 在具有多個 CPU 的機器上,gofmt現在應該明顯更快。

Vet

vue 現在支持泛型

例如,vet報告格式錯誤

func Print[T ~int|~string](t T) {
	fmt.Printf("%d", t)
}

因爲它會報告非通用等價的格式錯誤 Print[string]:

func PrintString(x 字符串) {
	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),以及GOARCH=amd64所有操作系統上的 64 位 x86 架構 ( )。在 64 位 ARM 和 64 位 PowerPC 系統上,基準測試顯示典型的性能提升 10% 或更多。

編譯器現在可以內聯包含範圍循環或標記爲循環的函數。

新的-asan編譯器選項支持新的go命令-asan選項。

因爲編譯器的類型檢查器被完全替換以支持泛型,一些錯誤消息現在可能使用與以前不同的措辭。在某些情況下,Go 1.18 之前的錯誤消息提供了更多詳細信息,或者以更有用的方式表述。我們打算在 Go 1.19 中解決這些情況。

由於與支持泛型相關的編譯器的更改,Go 1.18 的編譯速度可能比 Go 1.17 的編譯速度慢大約 15%。編譯代碼的執行時間不受影響。我們打算在未來的版本中提高編譯器的速度。

Linker (應該和彙編有關,沒用到過)

鏈接器發出的重定位要少得多。因此,大多數代碼庫將鏈接得更快,鏈接所需的內存更少,並生成更小的二進制文件。處理 Go 二進制文件的工具應該使用 Go 1.18 的debug/gosym包來透明地處理新舊二進制文件。

新的-asan鏈接器選項支持新的go命令-asan選項。

引導程序

從源代碼構建 Go 版本GOROOT_BOOTSTRAP 且未設置時,Go 的早期版本會在目錄中查找 Go 1.4 或更高版本的引導工具鏈$HOME/go1.4(%HOMEDRIVE%%HOMEPATH%\go1.4在 Windows 上)。Go 現在首先查找$HOME/go1.17或$HOME/sdk/go1.17 在回退到 之前查找$HOME/go1.4。我們打算讓 Go 1.19 要求 Go 1.17 或更高版本進行引導,並且此更改應該使過渡更順暢。有關更多詳細信息,請參閱go.dev/issue/44505。

核心庫

新debug/buildinfo包裝

新debug/buildinfo包提供對模塊版本、版本控制信息和嵌入在go命令構建的可執行文件中的構建標誌的訪問。runtime/debug.ReadBuildInfo 通過當前運行的二進制文件和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之間進行轉換的函數和方法 。 TCPAddrUDPAddrnetip.AddrPortTCPAddrFromAddrPortUDPAddrFromAddrPortTCPAddr.AddrPortUDPAddr.AddrPort

默認客戶端禁用 TLS 1.0 和 1.1

如果Config.MinVersion 未設置,它現在默認爲客戶端連接的 TLS 1.2。任何安全最新的服務器都應該支持 TLS 1.2,並且自 2020 年以來瀏覽器就需要它。通過設置 Config.MinVersion爲TLS 1.0 和 1.1 仍受支持VersionTLS10。服務器端默認值在 TLS 1.0 中保持不變。

GODEBUG=tls10default=1可以通過設置環境變量 將默認值暫時恢復爲 TLS 1.0 。此選項將在 Go 1.19 中刪除。

Rejecting SHA-1 certificates

crypto/x509現在將拒絕使用 SHA-1 哈希函數簽名的證書。這不適用於自簽名根證書。自 2017 年以來,已經證明了針對 SHA-1 的實際攻擊, 並且自 2015 年以來,公衆信任的證書頒發機構沒有頒發 SHA-1 證書。

這可以通過設置 GODEBUG=x509sha1=1環境變量來臨時恢復。此選項將在未來的版本中刪除。

庫的小改動

bufio (不太清楚作用,後面總結用法)

新Writer.AvailableBuffer 方法返回一個空緩衝區,其容量可能爲非空,以便與類似追加的 API 一起使用。附加後,緩衝區可以提供給後續Write調用,並可能避免任何複製。

Reader.Reset和 方法現在 在Writer.Reset對帶有 nil緩衝區的對象調用時使用默認緩衝區大小。

bytes

Cut()方法使用分隔符切割slice []byte, 它可以替代和簡化許多常見用途 Index, IndexByte, IndexRune, and 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 現在大約快四倍。所有特定的曲線實現現在都是恆定時間的。

對無效曲線點進行操作(方法返回 false 的那些點 IsOnCurve,並且從未被返回的Unmarshal或Curve在有效點上操作的方法)一直是未定義的行爲,可能導致密鑰恢復攻擊,現在新後端不支持. P224如果向、P384或方法提供了無效點 P521,則該方法現在將返回一個隨機點。在未來的版本中,該行爲可能會更改爲panic。

crypto/tls

新Conn.NetConn 方法允許訪問底層 net.Conn.

crypto/x509 (針對特定系統的)

Certificate.Verify 現在使用平臺 API 來驗證 macOS 和 iOS 上的證書有效性,當使用 nil VerifyOpts.Roots 調用它或使用從 SystemCertPool 返回的pool.

SystemCertPool 現在可在 Windows 上使用。

在 Windows、macOS 和 iOS 上,當 CertPool返回的 aSystemCertPool 添加了額外的證書時, Certificate.Verify 將執行兩種驗證:一種使用平臺驗證器 API 和系統根,另一種使用 Go 驗證器和附加根。平臺驗證者 API 返回的鏈將被優先考慮

CertPool.Subjects 已棄用。在 Windows、macOS 和 iOS 上, CertPool返回的 SystemCertPool 將返回一個池,該池不包括返回的切片中的系統根Subjects,因爲靜態列表無法恰當地表示平臺策略,並且可能根本無法從平臺 API 獲得。

MD5WithRSAGo 1.19 中可能會刪除 對使用依賴於 MD5 哈希 ( ) 的簽名算法的簽名證書的支持。

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

新Config.GoVersion 字段設置接受的 Go 語言版本。

爲了支持泛型,這裏添加了以下東西:

  • 添加了新類型 TypeParam、工廠函數 NewTypeParam和相關方法以表示類型參數。
  • 新類型 TypeParamList包含一個類型參數列表。
  • 新類型 TypeList包含一個類型列表。
  • 新的工廠函數 NewSignatureType分配一個 Signature帶有(接收器或函數)類型的參數。要訪問這些類型參數,該Signature類型有兩個新方法 Signature.RecvTypeParams和 Signature.TypeParams.
  • Named類型有四種新方法: Named.Origin獲取實例化類型的原始參數化類型, Named.TypeArgs獲取 Named.TypeParams實例化或參數化類型的類型實參或類型參數,以及 Named.SetTypeParams設置類型參數(例如,在導入命名類型時由於可能的循環,命名類型和類型參數的設置不能同時進行)。
  • 該Interface類型有四個新方法: 查詢接口定義的類型集的屬性, Interface.IsComparable以及 設置和 測試接口是否是圍繞類型約束字面量的隱式接口。 Interface.IsMethodSetInterface.MarkImplicitInterface.IsImplicit
  • 添加了新的類型 Unionand 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}}命令將立即開始下一個循環迭代。

在第一個評估爲假的參數之後停止評估參數

image/draw

當這些參數實現Go 1.17 中添加 的可選 和接口時, theDraw和DrawMaskfallback 實現(在參數不是最常見的圖像類型時使用)現在更快 。draw.RGBA64Imageimage.RGBA64Image

net

net.Error.Temporary已被棄用。

net/http

Dial, DialContext, DialTLS, DialTLSContext字段在Transport 將正確使用, 來發出 HTTP 請求

新 Cookie.Valid 方法報告 cookie 是否有效。

新 MaxBytesHandler 函數創建 Handler包裹它的 ResponseWriterand 和 Request.Body。

在查找包含非 ASCII 字符的域名時,Unicode 到 ASCII 的轉換現在按照 Unicode IDNA 兼容性處理標準 (UTS #46) 中定義的非過渡處理完成。改變了四種不同符文的解釋:ß、ς、零寬度連接符 U+200D 和零寬度非連接符 U+200C。非過渡處理與大多數應用程序和 Web 瀏覽器一致。

os/user

User.GroupIds 現在當 cgo 不可用時使用 Go 原生實現。

reflect

新的 Value.SetIterKey 和Value.SetIterValue 方法使用映射迭代器作爲源來設置一個值。它們等價於 Value.Set(iter.Key())and Value.Set(iter.Value()),但分配較少。

新 Value.UnsafePointer 方法將 Value 的值作爲unsafe.Pointer. 這允許調用者從調用站點遷移Value.UnsafeAddr 並Value.Pointer 消除執行 uintptr 到 unsafe.Pointer 轉換的需要(如 unsafe.Pointer 規則所要求的那樣)。

新 MapIter.Reset 方法更改其接收器以迭代不同的地圖。的使用 MapIter.Reset 允許在許多映射上進行無分配迭代。

添加了許多方法( Value.CanInt, Value.CanUint, Value.CanFloat, Value.CanComplex ) Value 來測試轉換是否安全。

Value.FieldByIndexErr 已添加以避免在單 Value.FieldByIndex 步執行指向嵌入式結構的 nil 指針時發生的恐慌。

reflect.Ptr和 reflect.PtrTo 已分別重命名爲 reflect.Pointer和 reflect.PointerTo,以與反射包的其餘部分保持一致。舊名稱將繼續有效,但將在未來的 Go 版本中棄用。

regexp

regexp 現在將 UTF-8 字符串的每個無效字節視爲U+FFFD.

runtime/debug

該BuildInfo 結構有兩個新字段,包含有關如何構建二進制文件的附加信息:

  • GoVersion 保存用於構建二進制文件的 Go 版本。
  • Settings 是一個 BuildSettings 結構切片,包含描述構建的鍵/值對。

runtime/pprof

CPU 分析器現在在 Linux 上使用每線程計時器。這增加了配置文件可以觀察到的最大 CPU 使用率,並減少了某些形式的偏差。

strconv

strconv.Unquote 現在拒絕代理一般 (這個翻譯有點問題,但是這個方法也沒用到過)

strings

新方法Cut代替和簡化 Index, IndexByte, IndexRune, and SplitN.

新方法Clone拷貝輸入的string 返回的不是輸入string的內存

Trim, TrimLeft, 和TrimRight 小型 ASCII 割集,速度提高了 10 倍。

Title 方法已棄用

sync

如果當前未持有鎖, Mutex.TryLock, RWMutex.TryLock, RWMutex.TryRLock 將獲取鎖。

syscall

SyscallN 爲 Windows 引入了 新函數,允許使用任意數量的參數進行調用。因此, 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類型由模糊測試使用。測試現在還支持命令行選項 -test.fuzz、-test.fuzztime 和 -test.fuzzminimizetime。

text/template

在range管道內,新 {{break}}命令將提前結束循環,新{{continue}}命令將立即開始下一個循環迭代。

and 函數不再總是計算所有參數; 它在第一個評估爲假的參數之後停止評估參數。 同樣, or 函數現在在第一個計算結果爲 true 的參數之後停止計算參數。 如果任何參數是函數調用,這會有所不同。

text/template/parse

該包支持text/template and html/template {{break}}命令,同樣通過新常量 NodeBreak 和新類型 BreakNode, 同樣通過新常量 NodeContinue 和新類型 ContinueNode 支持新的 {{continue}} 命令。

unicode/utf8

新方法 AppendRune 添加 UTF-8字符的一個rune 到一個[]byte 中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章