萬字長文告訴你Go 1.20中值得關(guān)注的幾個(gè)變化
美國時(shí)間2023年2月1日,唯一尚未退休的Go語言之父Robert Griesemer[1]代表Go核心開發(fā)團(tuán)隊(duì)在Go官博撰文正式發(fā)布了Go 1.20版本[2]。就像Russ Cox在2022 GopherCon大會(huì)[3]所說的那樣:**Go2永不會(huì)到來,Go 1.x.y將無限延續(xù)[4]**!
注:似乎新興編程語言都喜歡停留在1.x.y上無限延續(xù),譬如已經(jīng)演化到1.67版本的Rust[5]^_^。
在《Go,13周年》[6]之后,Go 1.20新特性在開發(fā)主干凍結(jié)(2022.11)之前,我曾寫過一篇《??Go 1.20新特性前瞻[??7]》,對(duì)照著Go 1.20 milestone[8]中內(nèi)容,把我認(rèn)為的主要特性和大家簡單過了一遍,不過那時(shí)Go 1.20畢竟沒有正式發(fā)布,前瞻肯定不夠全面,某些具體的點(diǎn)與正式版本可能也有差異!現(xiàn)在Go 1.20版本正式發(fā)布了,其Release Notes[9]也補(bǔ)充完整了,在這一篇中,我再來系統(tǒng)說說Go 1.20版本中值得關(guān)注的那些變化。對(duì)于在前瞻一文[10]中詳細(xì)介紹過的特性,這里不會(huì)再重復(fù)講解了,大家參考前瞻一文中的內(nèi)容即可。而對(duì)于其他一些特性,或是前瞻一文中著墨不多的特性,這里會(huì)挑重點(diǎn)展開說說。
按照慣例,我們依舊首先來看看Go語法層面都有哪些變化,這可能也是多數(shù)Gopher們最為關(guān)注的變化點(diǎn)。
一. 語法變化
Go秉持“大道至簡”的理念,對(duì)Go語法特性向來是“不與時(shí)俱進(jìn)”的。自從Go 1.18大刀闊斧的加入了泛型特性[11]后,Go語法特性就又恢復(fù)到了之前的“新三年舊三年,縫縫補(bǔ)補(bǔ)又三年”的節(jié)奏。Go 1.20亦是如此啊!Release Notes說Go 1.20版本在語言方面包含了四點(diǎn)變化,但看了變化的內(nèi)容后,我覺得真正的變化只有一個(gè),其他的都是修修補(bǔ)補(bǔ)。
1. 切片到數(shù)組的轉(zhuǎn)換
唯一算是真語法變化的特性是支持切片類型到數(shù)組類型(或數(shù)組類型的指針)的類型轉(zhuǎn)換,這個(gè)特性在前瞻一文[12]中系統(tǒng)講過,這里就不贅述了,放個(gè)例子大家直觀認(rèn)知一下就可以了:
有兩點(diǎn)注意一下就好:
- 切片轉(zhuǎn)換為數(shù)組類型的指針,那么該指針將指向切片的底層數(shù)組,就如同上面例子中slice2arrOK的parr變量那樣;
- 轉(zhuǎn)換的數(shù)組類型的長度不能大于原切片的長度(注意是長度而不是切片的容量哦),否則在運(yùn)行時(shí)會(huì)拋出panic。
2. 其他的修修補(bǔ)補(bǔ)
- comparable“放寬”了對(duì)泛型實(shí)參的限制
下面代碼在Go 1.20版本之前,比如Go 1.19版本中會(huì)無法通過編譯:
之前,comparable約束下的泛型形參需要支持嚴(yán)格可比較(strictly comparable)的類型作為泛型實(shí)參,哪些是嚴(yán)格可比較的類型呢?Go 1.20的語法規(guī)范做出了進(jìn)一步澄清:如果一個(gè)類型是可比較的,且不是接口類型或由接口類型組成的類型,那么這個(gè)類型就是嚴(yán)格可比較的類型,包括:
我們看到:例外的就是接口類型了。接口類型不是“嚴(yán)格可比較的(strictly comparable)”,但未作為類型形參的接口類型是可比較的(comparable),如果兩個(gè)接口類型的動(dòng)態(tài)類型相同且值相等,那么這兩個(gè)接口類型就相等,或兩個(gè)接口類型的值均為nil,它們也相等,否則不等。
Go 1.19版本及之前,作為非嚴(yán)格比較類型的接口類型是不能作為comparable約束的類型形參的類型實(shí)參的,就像上面comparable.go中示例代碼那樣,但Go 1.20版本開始,這一要求被防控,接口類型被允許作為類型實(shí)參賦值給comparable約束的類型形參了!不過這么做之前,你也要明確一點(diǎn),如果像下面這樣兩個(gè)接口類型底層類型相同且是不可比較的類型(比如切片),那么代碼將在運(yùn)行時(shí)拋panic:
Go 1.20語言規(guī)范借此機(jī)會(huì)還進(jìn)一步澄清了結(jié)構(gòu)體和數(shù)組兩種類型比較實(shí)現(xiàn)的規(guī)范:對(duì)于結(jié)構(gòu)體類型,Go會(huì)按照結(jié)構(gòu)體字段的聲明順序,逐一字段進(jìn)行比較,直到遇到第一個(gè)不相等的字段為止。如果沒有不相等字段,則兩個(gè)結(jié)構(gòu)體字段相等;對(duì)于數(shù)組類型,Go會(huì)按數(shù)組元素的順序,逐一元素進(jìn)行比較,直到遇到第一個(gè)不相等的元素為止。如果沒有不相等的元素,則兩個(gè)數(shù)組相等。
- unsafe包繼續(xù)添加“語法糖”
繼Go 1.17版本[13]在unsafe包增加Slice函數(shù)后,Go 1.20版本又增加三個(gè)語法糖函數(shù):SliceData、String和StringData:
值得注意的是由于string的不可更改性,String函數(shù)的參數(shù)ptr指向的內(nèi)容以及StringData返回的指針指向的內(nèi)容在String調(diào)用和StringData調(diào)用后不允許修改,但實(shí)際情況是怎么樣的呢?
我們看到:unsafe.String函數(shù)調(diào)用后,如果我們修改了傳入的指針指向的內(nèi)容,那么該改動(dòng)會(huì)影響到后續(xù)返回的string內(nèi)容!但StringData返回的指針?biāo)赶虻膬?nèi)容一旦被修改,就會(huì)導(dǎo)致運(yùn)行時(shí)的段錯(cuò)誤,從而程序崩潰!
二. 工具鏈
1. Go安裝包“瘦身”
這些年,Go發(fā)布版的安裝包“體格”是越來越壯了,動(dòng)輒100多MB的壓縮包,以go.dev/dl頁面上的go1.xy.linux-amd64.tar.gz為例,我們看看從Go 1.15版本到Go 1.19版本的“體格”變化趨勢:
如果按此趨勢,Go 1.20勢必要上到150MB以上。但Go團(tuán)隊(duì)找到了“瘦身”方法,那就是:從Go 1.20開始發(fā)行版的安裝包不再為GOROOT中的軟件包提供預(yù)編譯的.a文件了[14],這樣我們得到的瘦身后的Go 1.20版本的size為95MB!相較于Go 1.19,Go 1.20的安裝包“瘦”了三分之一。安裝包解壓后這種體現(xiàn)更為明顯:
我們看到:Go 1.20占用的磁盤空間僅為Go 1.19版本的一半多一點(diǎn)而已。并且,Go 1.20版本中,GOROOT下的源碼將像其他用戶包那樣在構(gòu)建后被緩存到本機(jī)cache中。此外,go install也不會(huì)為GOROOT下的軟件包安裝.a文件。
2. 編譯器
1) PGO(profile-guided optimization)
Go 1.20編譯器的一個(gè)最大的變更點(diǎn)是引入了PGO優(yōu)化技術(shù)預(yù)覽版,這個(gè)在前瞻一文中也有對(duì)PGO技術(shù)的簡單介紹[15]。說白了點(diǎn),PGO技術(shù)就是在原有compiler優(yōu)化技術(shù)的基礎(chǔ)上,針對(duì)程序在生產(chǎn)環(huán)境運(yùn)行中的熱點(diǎn)關(guān)鍵路徑再進(jìn)行一輪優(yōu)化,并且針對(duì)熱點(diǎn)代碼執(zhí)行路徑,編譯器會(huì)放開一些限制,比如Go決定是否對(duì)函數(shù)進(jìn)行內(nèi)聯(lián)優(yōu)化的復(fù)雜度上限默認(rèn)值是80[16],但對(duì)于PGO指示的關(guān)鍵熱點(diǎn)路徑,即便函數(shù)復(fù)雜性超過80很多,也可能會(huì)被inline優(yōu)化掉。
之前持續(xù)性能剖析工具開發(fā)商Polar Signals曾發(fā)布一篇文章《Exploring Go's Profile-Guided Optimizations》[17],專門探討了PGO技術(shù)可能帶來的優(yōu)化效果,文章中借助了Go項(xiàng)目中自帶的測試示例,這里也基于這個(gè)示例帶大家重現(xiàn)一下。
我們使用的例子在Go 1.20源碼/安裝包的$GOROOT/src/cmd/compile/internal/test/testdata/pgo/inline路徑下:
我們首先執(zhí)行一下inline目錄下的測試,并生成用于測試的可執(zhí)行文件以及對(duì)應(yīng)的cpu profile文件供后續(xù)PGO優(yōu)化使用:
接下來,我們對(duì)比一下不使用PGO和使用PGO優(yōu)化,Go編譯器在內(nèi)聯(lián)優(yōu)化上的區(qū)別:
上面diff命令中為Go test命令傳入-run=none -tags="" -gcflags="-m -m"是為了僅編譯源文件,而不執(zhí)行任何測試。
我們看到,相較于未使用PGO優(yōu)化的結(jié)果,PGO優(yōu)化后的結(jié)果多了兩個(gè)inline函數(shù),這兩個(gè)可以被inline的函數(shù),一個(gè)的復(fù)雜度開銷為106,一個(gè)是312,都超出了默認(rèn)的80,但仍然可以被inline。
我們來看看PGO的實(shí)際優(yōu)化效果,我們分為在無PGO優(yōu)化與有PGO優(yōu)化下執(zhí)行100次benchmark,再用benchstat工具對(duì)比兩次的結(jié)果:
注:benchstat的安裝方法:$go install golang.org/x/perf/cmd/benchstat@latest
我們看到,在我的機(jī)器上(ubuntu 20.04 linux kerenel 5.4.0-132),PGO針對(duì)這個(gè)測試的優(yōu)化效果并不明顯(僅僅有0.24%的提升),Polar Signals原文中的提升幅度也不大,僅為1.05%。
Go官方Release Notes中提到benchmark提升效果為3%~4%,同時(shí)官方也提到了,這個(gè)僅僅是PGO初始技術(shù)預(yù)覽版,后續(xù)會(huì)加強(qiáng)對(duì)PGO優(yōu)化的投入,直至對(duì)多數(shù)程序產(chǎn)生較為明顯的優(yōu)化效果。個(gè)人覺得目前PGO尚處于早期,不建議在生產(chǎn)中使用。
Go官方也增加針對(duì)PGO的ref頁面[18],大家重點(diǎn)看看其中的FAQ,你會(huì)有更多收獲!
2) 構(gòu)建速度
Go 1.18泛型落地后,Go編譯器的編譯速度出現(xiàn)了回退(幅度15%),Go 1.19編譯速度也沒有提升。雖然編譯速度回退后依然可以“秒殺”競爭對(duì)手,但對(duì)于以編譯速度快著稱的Go來說,這個(gè)問題必須修復(fù)。Go 1.20做到了這一點(diǎn),讓Go編譯器的編譯速度重新回歸到了Go 1.17的水準(zhǔn)!相對(duì)Go 1.19提升10%左右。
我使用github.com/reviewdog/reviewdog這個(gè)庫實(shí)測了一下,分別使用go 1.17.1、go 1.18.6、go 1.19.1和Go 1.20對(duì)這個(gè)module進(jìn)行g(shù)o build -a構(gòu)建(之前將依賴包都下載本地,排除掉go get環(huán)節(jié)的影響),結(jié)果如下:
雖然不能十分精確,但總體上反映出各個(gè)版本的編譯速度水準(zhǔn)以及Go 1.20相對(duì)于Go 1.18和Go 1.19版本的提升。我們看到Go 1.20與Go 1.17版本在一個(gè)水平線上,甚至要超過Go 1.17(但可能僅限于我這個(gè)個(gè)例)。
3) 允許在泛型函數(shù)/方法中進(jìn)行類型聲明
Go 1.20版本之前下面代碼是無法通過Go編譯器的編譯的:
Go 1.20改進(jìn)了語言前端的實(shí)現(xiàn)[19],通過unified IR實(shí)現(xiàn)了對(duì)在泛型函數(shù)/方法中進(jìn)行類型聲明(包括定義type alias)的支持。
同時(shí),Go 1.20在spec[20]中還明確了哪些使用了遞歸方式聲明的類型形參列表是不合法的[21]:
4) 構(gòu)建自舉源碼的Go編譯器的版本選擇
Go從Go 1.5版本開始實(shí)現(xiàn)自舉,即使用Go實(shí)現(xiàn)Go,那么自舉后的Go項(xiàng)目是誰來編譯的呢?最初對(duì)應(yīng)編譯Go 1.5版本的Go編譯器版本為Go 1.4。
以前從源碼構(gòu)建Go發(fā)行版,當(dāng)未設(shè)置GOROOT_BOOTSTRAP時(shí),編譯腳本會(huì)默認(rèn)使用Go 1.4,但如果有更高版本的Go編譯器存在,會(huì)使用更高版本的編譯器。
Go 1.18和Go 1.19會(huì)首先尋找是否有g(shù)o 1.17版本,如果沒有再使用go 1.4。
Go 1.20會(huì)尋找當(dāng)前Go 1.17的最后一個(gè)版本Go 1.17.13,如果沒有,則使用Go 1.4。
將來,Go核心團(tuán)隊(duì)計(jì)劃一年升級(jí)一次構(gòu)建自舉源碼的Go編譯器的版本,例如:Go 1.22版本將使用Go 1.20版本的編譯器。
5) cgo
Go命令現(xiàn)在在沒有C工具鏈的系統(tǒng)上會(huì)默認(rèn)禁用了cgo。更具體來說,當(dāng)CGO_ENABLED環(huán)境變量未設(shè)置,CC環(huán)境變量未設(shè)置以及PATH環(huán)境變量中沒有找到默認(rèn)的C編譯器(通常是clang或gcc)時(shí),CGO_ENABLED會(huì)被默認(rèn)設(shè)置為0。
3. 其他工具
1) 支持采集應(yīng)用執(zhí)行的代碼蓋率
在前瞻一文中,我提到過Go 1.20將對(duì)代碼覆蓋率的支持?jǐn)U展到了應(yīng)用整體層面,而不再僅僅是unit test。這里使用一個(gè)例子來看一下,究竟如何采集應(yīng)用代碼的執(zhí)行覆蓋率。我們以gitlab.com/esr/loccount這個(gè)代碼統(tǒng)計(jì)工具為例,先修改一下Makefile,在go build后面加上-cover選項(xiàng),然后編譯loccount,并對(duì)其自身進(jìn)行代碼統(tǒng)計(jì):
上面執(zhí)行l(wèi)occount之前,我們建立了一個(gè)mycovdata目錄,并設(shè)置GOCOVERDIR的值為mycovdata目錄的路徑。在這樣的上下文下,執(zhí)行l(wèi)occount后,mycovdata目錄下會(huì)生成一些覆蓋率統(tǒng)計(jì)數(shù)據(jù)文件:
怎么查看loccount的執(zhí)行覆蓋率呢?我們使用go tool covdata來查看:
當(dāng)然, covdata子命令還支持其他一些功能,大家可以自行查看manual挖掘。
2) vet
Go 1.20版本中,go工具鏈的vet子命令增加了兩個(gè)十分實(shí)用的檢測:
- 對(duì)loopclosure這一檢測策略進(jìn)行了增強(qiáng)
具體可參見https://github.com/golang/tools/tree/master/go/analysis/passes/loopclosure代碼
- 增加對(duì)2006-02-01的時(shí)間格式的檢查
注意我們使用time.Format或Parse時(shí),最常使用的是2006-01-02這樣的格式,即ISO 8601標(biāo)準(zhǔn)的時(shí)間格式,但一些代碼中總是出現(xiàn)2006-02-01,十分容易導(dǎo)致錯(cuò)誤。這個(gè)版本中,go vet將會(huì)對(duì)此種情況進(jìn)行檢查。
三. 運(yùn)行時(shí)與標(biāo)準(zhǔn)庫
1. 運(yùn)行時(shí)(runtime)
Go 1.20運(yùn)行時(shí)的調(diào)整并不大,僅對(duì)GC的內(nèi)部數(shù)據(jù)結(jié)構(gòu)進(jìn)行了微調(diào),這個(gè)調(diào)整可以獲得最多2%的內(nèi)存開銷下降以及cpu性能提升。
2. 標(biāo)準(zhǔn)庫
標(biāo)準(zhǔn)庫肯定是變化最多的那部分。前瞻一文中對(duì)下面變化也做了詳細(xì)介紹,這里不贅述了,大家可以翻看那篇文章細(xì)讀:
- 支持wrap multiple errors
- time包新增DateTime、DateOnly和TimeOnly三個(gè)layout格式常量
- 新增arena包 ... ...
標(biāo)準(zhǔn)庫變化很多,這里不能一一羅列,再補(bǔ)充一些我認(rèn)為重要的,其他的變化大家可以到Go 1.20 Release Notes[22]去看:
1) arena包
前瞻一文已經(jīng)對(duì)arena包做了簡要描述,對(duì)于arena包的使用以及最佳適用場合的探索還在進(jìn)行中。著名持續(xù)性能剖析工具pyroscope[23]的官方博客文章《Go 1.20 arenas實(shí)踐:arena vs. 傳統(tǒng)內(nèi)存管理》[24]對(duì)于arena實(shí)驗(yàn)特性的使用給出了幾點(diǎn)好的建議,比如:
- 只在關(guān)鍵的代碼路徑中使用arena,不要到處使用它們
- 在使用arena之前和之后對(duì)你的代碼進(jìn)行profiling,以確保你在能提供最大好處的地方添加arena。
- 密切關(guān)注arena上創(chuàng)建的對(duì)象的生命周期。確保你不會(huì)把它們泄露給你程序中的其他組件,因?yàn)槟抢锏膶?duì)象可能會(huì)超過arena的壽命。
- 使用defer a.Free()來確保你不會(huì)忘記釋放內(nèi)存。
- 如果你想在arena被釋放后使用對(duì)象,使用arena.Clone()將其克隆回heap中。
pyroscope的開發(fā)人員認(rèn)為arena是一個(gè)強(qiáng)大的工具,也支持標(biāo)準(zhǔn)庫中保留arena這個(gè)特性,但也建議將arena和reflect、unsafe、cgo等一樣納入“不推薦”使用的包行列。這點(diǎn)我也是贊同的。我也在考慮如何基于arena改進(jìn)我們產(chǎn)品的協(xié)議解析器的性能,有成果后,我也會(huì)將實(shí)踐過程分享出來的。
2) 新增crypto/ecdh包
密碼學(xué)包(crypto)的主要maintainer Filippo Valsorda[25]從google離職后,成為了一名專職開源項(xiàng)目維護(hù)者[26]。這似乎讓其更有精力和動(dòng)力對(duì)crypto包進(jìn)行更好的規(guī)劃、設(shè)計(jì)和實(shí)現(xiàn)了。crypto/ecdh包就是在他的提議下加入到Go標(biāo)準(zhǔn)庫中的[27]。
相對(duì)于標(biāo)準(zhǔn)庫之前存在的crypto/elliptic等包,crypto/ecdh包的API更為高級(jí),Go官方推薦使用ecdh的高級(jí)API,這樣大家以后可以不必再與低級(jí)的密碼學(xué)函數(shù)斗爭了。
3) HTTP ResponseController
以前HTTP handler的超時(shí)都是http服務(wù)器全局指定一個(gè)的:包括ReadTimeout和WriteTimeout。但有些時(shí)候,如果能在某個(gè)請(qǐng)求范圍內(nèi)支持這些超時(shí)(以及可能的其他選項(xiàng))將非常有用。Damien Neil就創(chuàng)建了這個(gè)增加ResponseController的提案[28],下面是一個(gè)在HandlerFunc中使用ResponseController的例子:
4) context包增加WithCancelCause函數(shù)
context包新增了一個(gè)WithCancelCause函數(shù),與WithCancel不同,通過WithCancelCause返回的Context,我們可以得到cancel的原因,比如下面示例:
我們看到通過context.Cause可以得到Context在cancel時(shí)傳入的錯(cuò)誤原因。
四. 移植性
Go對(duì)新cpu體系結(jié)構(gòu)和OS的支持向來是走在前面的。Go 1.20還新增了對(duì)freebsd在risc-v上的實(shí)驗(yàn)性支持,其環(huán)境變量為GOOS=freebsd, GOARCH=riscv64。但Go 1.20也將成為對(duì)下面平臺(tái)提供支持的最后一個(gè)Go版本:
- Windows 7, 8, Server 2008和Server 2012
- MacOS 10.13 High Sierra和10.14 (我的安裝了10.14的mac os又要在go 1.21不被支持了^_^)
近期Go團(tuán)隊(duì)又有了新提案:支持WASI(GOOS=wasi GOARCH=wasm)[29],WASI是啥,它是WebAssembly一套與引擎無關(guān)(engine-indepent)的、面向非Web系統(tǒng)的WASM API標(biāo)準(zhǔn),是WebAssembly脫離瀏覽器的必經(jīng)之路!一旦生成滿足WASI的WASM程序,該程序就可以在任何支持WASI或兼容的runtime上運(yùn)行。不出意外,該提案將在Go 1.21或Go 1.22版本落地。
本文中的示例代碼可以在這里[30]下載。
Gopher Daily(Gopher每日新聞)歸檔倉庫 - https://github.com/bigwhite/gopherdaily
- 微博(暫不可用):https://weibo.com/bigwhite20xx
- 微博2:https://weibo.com/u/6484441286
- 博客:tonybai.com
- github: https://github.com/bigwhite
參考資料
[1] Robert Griesemer: https://github.com/griesemer
[2] Go官博撰文正式發(fā)布了Go 1.20版本: https://go.dev/blog/go1.20
[3] Russ Cox在2022 GopherCon大會(huì): https://www.youtube.com/watch?v=v24wrd3RwGo
[4] Go2永不會(huì)到來,Go 1.x.y將無限延續(xù): https://tonybai.com/2022/12/29/the-2022-review-of-go-programming-language
[5] 演化到1.67版本的Rust: https://www.rust-lang.org
[6] 《Go,13周年》: https://tonybai.com/2022/11/11/go-opensource-13-years/
[7] Go 1.20新特性前瞻: https://tonybai.com/2022/11/17/go-1-20-foresight
[8] Go 1.20 milestone: https://github.com/golang/go/milestone/250
[9] Release Notes: https://go.dev/blog/go1.20
[10] 前瞻一文: https://tonybai.com/2022/11/17/go-1-20-foresight
[11] Go 1.18大刀闊斧的加入了泛型特性: https://tonybai.com/2022/04/20/some-changes-in-go-1-18
[12] 前瞻一文: https://tonybai.com/2022/11/17/go-1-20-foresight
[13] Go 1.17版本: https://tonybai.com/2021/08/17/some-changes-in-go-1-17
[14] 從Go 1.20開始發(fā)行版的安裝包不再為GOROOT中的軟件包提供預(yù)編譯的.a文件了: https://github.com/golang/go/issues/47257
[15] 對(duì)PGO技術(shù)的簡單介紹: https://tonybai.com/2022/11/17/go-1-20-foresight
[16] Go決定是否對(duì)函數(shù)進(jìn)行內(nèi)聯(lián)優(yōu)化的復(fù)雜度上限默認(rèn)值是80: https://tonybai.com/2022/10/17/understand-go-inlining-optimisations-by-example
[17] 《Exploring Go's Profile-Guided Optimizations》: https://www.polarsignals.com/blog/posts/2022/09/exploring-go-profile-guided-optimizations/
[18] PGO的ref頁面: https://go.dev/doc/pgo
[19] Go 1.20改進(jìn)了語言前端的實(shí)現(xiàn): https://github.com/golang/go/issues/47631
[20] spec: https://go.dev/ref/spec#Type_parameter_declarations
[21] 哪些使用了遞歸方式聲明的類型形參列表是不合法的: https://github.com/golang/go/issues/40882
[22] Go 1.20 Release Notes: https://go.dev/doc/go1.20
[23] pyroscope: https://pyroscope.io/
[24] 《Go 1.20 arenas實(shí)踐:arena vs. 傳統(tǒng)內(nèi)存管理》: https://pyroscope.io/blog/go-1-20-memory-arenas/
[25] Filippo Valsorda: https://filippo.io/
[26] 成為了一名專職開源項(xiàng)目維護(hù)者: https://words.filippo.io/full-time-maintainer/
[27] crypto/ecdh包就是在他的提議下加入到Go標(biāo)準(zhǔn)庫中的: https://github.com/golang/go/issues/52221
[28] 增加ResponseController的提案: https://github.com/golang/go/issues/54136
[29] 支持WASI(GOOS=wasi GOARCH=wasm): https://github.com/golang/go/issues/58141
[30] 這里: https://github.com/bigwhite/experiments/blob/master/go1.20-examples
[31] “Gopher部落”知識(shí)星球: https://wx.zsxq.com/dweb2/index/group/51284458844544
本文轉(zhuǎn)載自微信公眾號(hào)「 白明的贊賞賬戶」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系白明的贊賞賬戶公眾號(hào)。