golang1.16新特性速覽(推薦)
golang1.16也在今天正式發佈瞭。
原定計劃是2月1號年前發佈的,不過遲到也是golang的老傳統瞭,正好也趁著最後的假期快速預覽一下golang1.16的新特性吧。
語言內建的資源嵌入支持
之前市面上已經有很多把今天文件嵌入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
到此這篇關於golang1.16新特性速覽的文章就介紹到這瞭,更多相關golang1.16新特性速覽內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Golang 1.16 中 Modules的主要變化更新
- golang官方嵌入文件到可執行程序的示例詳解
- Golang嵌入資源文件實現步驟詳解
- Golang中panic的異常處理
- Golang 單元測試和基準測試實例詳解