Go1.16 正式發佈,如下變動你須要知道

如有任何問題或建議,歡迎及時交流和碰撞。個人公衆號是 【腦子進煎魚了】,GitHub 地址: https://github.com/eddycjy

你們好,我是正在努力學習的煎魚。ios

在前幾天,Go1.16rc1 搶先發布了。結合常規的 28 發佈規律,其將會在 2021.02 月份左右發佈正式版本。git

image.png

此次 Go1.16 也帶來了一些新特性或變動。那麼做爲一個 Gopher,想必不能錯過此次的更新。github

image.png

今天這篇文章將會帶你們瞭解一下 Go1.16 的幾個須要關注的特性。golang

廢棄 io/ioutil

Go 官方認爲 io/ioutil 這個包的定義不明確且難以理解。因此 Russ Cox 在 2020.10.17 提出了廢棄 io/ioutil 的提案。json

大體變動以下:微信

  • Discard => io.Discard
  • NopCloser => io.NopCloser
  • ReadAll => io.ReadAll
  • ReadDir => os.ReadDir
  • ReadFile => os.ReadFile
  • TempDir => os.MkdirTemp
  • TempFile => os.CreateTemp
  • WriteFile => os.WriteFile

與此同時你們也不須要擔憂存在破壞性變動,由於有 Go1 兼容性的保證,在 Go1 中 io/ioutil 還會存在,只變動內部的方法調用:網絡

func ReadAll(r io.Reader) ([]byte, error) {
    return io.ReadAll(r)
}

func ReadFile(filename string) ([]byte, error) {
    return os.ReadFile(filename)
}

你們在後續也能夠改改調用習慣。架構

支持靜態資源嵌入

若是咱們但願把靜態文件編譯進 Go 的二進制文件的話,在以往須要藉助 go-bindata/go-bindata 這類第三方開源庫來實現。app

而從 Go1.16 起,經過 go:embed 就能夠快速實現這個功能:函數

import _ "embed"

//go:embed hello.txt
var s string
print(s)

經過對變量 s 聲明 go:embed 指令,使其在編譯時讀取當前目錄下的 hello.txt 文件。

最終變量 s 就會輸出 hello.txt 文件中的字符串內容。

新增 io/fs 的支持

新增了標準庫 io/fs,正式將文件系統相關的基礎接口抽象到了該標準庫中。

之前的話大可能是在 os 標準庫中,這一步抽離更進一步的抽象了文件樹的接口。在後續的版本中,你們能夠優先考慮使用 io/fs 標準庫。

調整切片擴容策略

Go1.16 之前的 slice 的擴容條件是 len,在最新的代碼中,已經改成了以 cap 屬性做爲基準:

// src/runtime/slice.go
    if cap > doublecap {
        newcap = cap
    } else {
        // 這是之前的代碼:if old.len < 1024 {
        // 下面是 Go1.16rc1 的代碼
        if old.cap < 1024 {
            newcap = doublecap
        }

以官方的 test case 爲例:

func main() {
    const N = 1024
    var a [N]int
    x := cap(append(a[:N-1:N], 9, 9))
    y := cap(append(a[:N:N], 9))
    println(cap(x), cap(y))
}

在 Go1.16 之前輸出 2048, 1280。在 Go1.16 及之後輸出 1280, 1280,保證了兩種的一致。

支持 Apple Silicon M1

衆所周知,最新版本的 Mac 採用了新的 64 位 ARM 架構,所以在 Go1.16 後正式支持了 GOOS=darwinGOARCH=arm64

而相應的先前用於 iOS 端口的,將改成 GOOS=iosGOARCH=arm64

同時 Apple M1 能不能很好的跑好 Go 語言程序也是各大微信羣愛討論的問題,在 GoLand 上:

圖來自網絡,路過微信羣看見

須要注意,GoLand 的一些給你要到後續的新版本才能夠使用。

調整 Go modules 策略

從 Go1.16 起,Go modules 的環境變量 GO111MODULE 默認開關將爲 on,再也不是以前是 auto 了。

還在使用 GOPATH,或 Go modules 沒切全的同窗這一塊須要特別注意。

新增 GODEBUG inittrace

GODEBUG 新增 inittrace 指令,能夠用於 init 方法的排查:

$ GODEBUG=inittrace=1 go run main.go

輸出結果:

init internal/bytealg @0.008 ms, 0 ms clock, 0 bytes, 0 allocs
init runtime @0.059 ms, 0.026 ms clock, 0 bytes, 0 allocs
init math @0.19 ms, 0.001 ms clock, 0 bytes, 0 allocs
init errors @0.22 ms, 0.004 ms clock, 0 bytes, 0 allocs
init strconv @0.24 ms, 0.002 ms clock, 32 bytes, 2 allocs
init sync @0.28 ms, 0.003 ms clock, 16 bytes, 1 allocs
init unicode @0.44 ms, 0.11 ms clock, 23328 bytes, 24 allocs
...

主要做用是 init 函數跟蹤的支持,以用於 init 調試和啓動時間的概要分析,算是一個 GODEBUG 的補充功能點。

簡化結構體標籤

在 Go 語言的結構體中,咱們經常會由於各類庫的訴求,須要對結構體的 tag 設置標識。

若是像是之前,量比較多就會變成:

type MyStruct struct {
  Field1 string `json:"field_1,omitempty" bson:"field_1,omitempty" xml:"field_1,omitempty" form:"field_1,omitempty" other:"value"`
}

但在 Go1.16 及之後,就能夠經過合併的方式:

type MyStruct struct {
  Field1 string `json,bson,xml,form:"field_1,omitempty" other:"value"`
}

方便和簡潔了很多。

總結

在本次 Go1.16 中帶來了很多小優化和新的特性支持。離 Go1.18 的泛型又近了一步。

另外在本次新版本中,像是 template 支持跨行:

{{"hello" |
   printf}}

又或是 Linux 的默認內存管理策略下又從 MADV_FREE 改回了 MADV_DONTNEED 策略,你們在新版本中再也不須要設置:

GODEBUG=madvdontneed=1

你們如有需求均可以進一步去了解,如今新版本的功能特性已經鎖定,基本塵埃落定。

傳送門:https://tip.golang.org/doc/go...

個人公衆號

分享 Go 語言、微服務架構和奇怪的系統設計,歡迎你們關注個人公衆號和我進行交流和溝通。

最好的關係是互相成就,各位的點贊就是煎魚創做的最大動力,感謝支持。

相關文章
相關標籤/搜索