今天是假期最后一天,明天起大家也要陸續復工了,golang1.16也在今天正式發布了,
原定計劃是2月1號年前發布的,不過遲到也是golang的老傳統了,正好也趁著最后的假期快速預覽一下golang1.16的新特性吧,
本文索引
- 語言內建的資源嵌入支持
- 支持arm64
- go modules的新特性
- GO111MODULE現在默認為on
- go build不在更改mod相關檔案
- go install的變化
- 新的GOVCS環境變數
- 相對路徑匯入不在被允許
- 標準庫的變化
- testing
- ioutils包已經廢棄
- tcp半連接佇列擴容
- 重大更新io/fs
- 其他改進
語言內建的資源嵌入支持
之前市面上已經有很多把今天檔案嵌入golang二進制程式的工具了,這次golang官方將這一功能加入了embed標準庫,從語言層面上提供了支持,
我之前以及寫了embed的使用教程,可以看這里,
這兒還有一篇官方推薦的教程,
支持arm64
m1芯片可謂是最近的焦點,golang自然也不會落下,
在golang1.16中官方已經支持darwin/arm64平臺,cgo和編譯成c語言可呼叫的動態/靜態鏈接庫的功能也已支持,同樣受益的還有bsd家族的arm64版本,
現在可以在新版mac上嘗試golang了,
不過plugin模式的支持仍在進行中,想要完整支持arm64還需要一段時間,
go modules的新特性
本次更新依舊帶來了許多modules的新特性,
GO111MODULE現在默認為on
1.16開始默認啟用modules,這在1.15的時候已經預告過了,現在GO111MODULE的默認值為on,
不過golang還是提供了一個版本的適應期,如果你還不習慣modules,可以把GO111MODULE設定回auto,在1.17中這個環境變數將會被洗掉,
都1202年了,也該學學go modules怎么用了,
go build不再更改mod相關檔案
以前的教程里我提到過go build會自動下載依賴,這會更新mod檔案,
現在這一行為被禁止了,想要安裝、更新依賴只能使用go get命令,go build和go test將不會再做這類作業,
go install的變化
go install在1.16中也有了不小的變化,
首先是通過go install my.module/[email protected] 這樣在module末尾加上版本號,可以在不影響當前mod的依賴的情況下安裝golang程式,
go install是未來唯一可以安裝golang程式的命令,go get的編譯安裝功能現在可以靠-d選項關閉,而未來編譯安裝功能會從go get移除,
也就是說go的命令各司其職,不再長臂管轄了,
新的GOVCS環境變數
新的GOVCS環境變數指定了golang用什么版本控制工具下載源代碼,
其格式為:GOVCS=<module prefix>:<tool name>,[<module prefix>:<tool name>, ...]
其中module prefix為github.com等,而tool name就是版本控制工具的名字,比如git,svn,
一個更具體的例子是:GOVCS=github.com:git,evil.com:off,*:git|hg
module prefix也可以用*通配任何模塊的前綴,
tool name還可以設定為all和off,all代表允許使用任何可用的工具,而off則表示不允許使用任何版本控制工具,
不過現在設定為off的模塊的代碼仍然可能會被下載,
更多的細節可以參考go help vcs,
相對路徑匯入不在被允許
golang1.16開始禁止import匯入的模塊以.開頭,模塊路徑中也不允許出現任何非ASCII字符,所以下面的代碼不再合法:
import (
"./tools/factory"
"../models/user"
"some.pkg.com/殺馬特/音樂工廠"
)
對非ASCII字符一如既往的不友好,不過也只能按規矩辦事了,
標準庫的變化
golang1.16除了對標準庫進行通常的功能更新和修復,還引入了一些重大變化,
testing
testing包主要的變化是在測驗用例里呼叫os.Exit(0)會從程式終止變成測驗失敗,
比如這個:
package main
import (
"os"
"testing"
)
func TestXXX(t *testing.T) {
t.Log("exit")
os.Exit(0)
}
現在會是這樣的輸出:
$ go test -v a_test.go
=== RUN TestXXX
a_test.go:9: exit
--- FAIL: TestXXX (0.00s)
panic: unexpected call to os.Exit(0) during test [recovered]
panic: unexpected call to os.Exit(0) during test
goroutine 18 [running]:
testing.tRunner.func1.2(0x51b920, 0x56cc28)
/usr/local/go/src/testing/testing.go:1144 +0x332
testing.tRunner.func1(0xc000082600)
/usr/local/go/src/testing/testing.go:1147 +0x4b6
panic(0x51b920, 0x56cc28)
/usr/local/go/src/runtime/panic.go:965 +0x1b9
os.Exit(0x0)
/usr/local/go/src/os/proc.go:68 +0x6d
command-line-arguments.TestXXX(0xc000082600)
/tmp/a_test.go:10 +0x76
testing.tRunner(0xc000082600, 0x54df18)
/usr/local/go/src/testing/testing.go:1194 +0xef
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1239 +0x2b3
FAIL command-line-arguments 0.004s
FAIL
ioutils包已經廢棄
1.16已經標記io/ioutil為廢棄,函式被轉移到了os和io這兩個包里,具體見下表:
| ioutil舊函式 | 新函式 |
|---|---|
| Discard | io.Discard |
| NopCloser | io.NopCloser |
| ReadAll | io.ReadAll |
| ReadDir | os.ReadDir |
| ReadFile | os.ReadFile |
| WriteFile | os.WriteFile |
| TempDir | os.MkdirTemp |
| TempFile | os.CreateTemp |
現在開始可以做移植了,
tcp半連接佇列擴容
在Linux kernel 4.1以前,golang設定tcp的listen佇列的長度是從/proc/sys/net/core/somaxconn獲取的,通常為4096,
而在4.1以后golang會直接設定半連接佇列的長度為2^32 - 1也就是4294967295,
更大的半連接佇列意味著可以同時處理更多的新加入請求,而且不用再讀取組態檔性能也會略微提升,
重大更新io/fs
1.16除了支持嵌入靜態資源外,最大的變化就是引入了io/fs包,
golang認為檔案的io操作是依賴于檔案系統(filesystem,fs)的,所以決定模仿Linux的vfs做一套基于fs的io介面,
這樣做的目的有三個:
- os包應該專注于和系統互動而不是包含一部分io介面
- io包和os包分別包含了io介面的一部分,導致互相依賴職責不清晰
- 可以把有關聯的一部分檔案或者資料組成虛擬檔案系統,供通用介面處理提升程式的可擴展性,比如zip打包的檔案
所以io/fs誕生了,
fs包中主要包含了下面幾種資料型別(都是介面型別):
| 名稱 | 作用 |
|---|---|
| FS | 檔案系統的抽象,有一個Open方法用來從FS打開獲取檔案資料 |
| DirEntry | 描述目錄專案(包含目錄自身)的資料結構 |
| File | 描述檔案資料的結構,包含Stat,Read,Close方法 |
| ReadDirFile | 在File的基礎上支持ReadDir,可以代表目錄自身 |
| FileMode | 描述檔案型別,比如是通常檔案還是套接字或者是管道 |
| FileInfo | 檔案的元資料,例如創建時間等 |
其中有一些介面和os包中的同名,實際上是os包引入fs包后起的別名,
對于FS,還有以下的擴展,以便增量描述檔案系統允許的操作:
| 名稱 | 作用 |
|---|---|
| GlobFS | 增加Glob方法,可以用通配符查找檔案 |
| ReadDirFS | 增加ReadDir方法,可以遍歷目錄 |
| ReadFileFS | 增加ReadFile方法,可以用檔案名讀取檔案所有內容 |
| StatFS | 增加Stat方法,可以獲得檔案/目錄的元資訊 |
| SubFS | 增加Sub方法,Sub方法接受一個檔案/目錄的名字,從這個名字作為根目錄回傳一個新的檔案系統物件 |
fs包還提供了諸如Glob,WalkDir等傳統的檔案操作介面,
fs的主要威力在于處理zip、tar檔案,以及http的檔案介面時可以大幅簡化代碼,而且新的embed靜態資源嵌入也是依賴fs實作的,
因為只是速覽的緣故,無法詳盡介紹io/fs包,你可以參考golang的檔案或這篇文章做進一步了解,
其他改進
其他的改進包括Unicode更新到了13.0、新增加了runtime/metrics包已提供更好更規范的運行時資訊等,
同時1.16優化了聯結器,現在它在linux/amd64上比1.15快了20-25%,記憶體占用減少了5-15%,
在Windows上已經全面支持了地址空間布局隨機化(ASLR),此前不支持將golang編譯為dll時啟用ASLR,
本次更新中語言本身沒有什么變化,
更多資訊可以查看golang1.16 release notes
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/260465.html
標籤:Go
