“Go 語(yǔ)言的優(yōu)點(diǎn)、缺點(diǎn)和平淡無(wú)奇之處”的十年(go 語(yǔ)言 優(yōu)勢(shì)及 主要用途)
【編者按】本文作者對(duì)他在十年前撰寫(xiě)的一篇名為 “Go 語(yǔ)言:優(yōu)點(diǎn)、缺點(diǎn)和平淡無(wú)奇之處” 的文章進(jìn)行回顧和更新,討論了他的準(zhǔn)確預(yù)測(cè)、Go 語(yǔ)言的變化以及他之前的疏漏。本文見(jiàn)證了 GO 語(yǔ)言這十年的演進(jìn)歷程。
原文鏈接:https://blog.carlmjohnson.net/post/2023/ten-years-of-go-good-bad-meh/
未經(jīng)允許,禁止轉(zhuǎn)載!
作者 | Carl M. Johnson 譯者 | 明明如月
責(zé)編 | 夏萌
出品 | CSDN(ID:CSDNnews)
十年前,我撰寫(xiě)了一篇名為Go 語(yǔ)言:優(yōu)點(diǎn)、缺點(diǎn)和平淡無(wú)奇之處(鏈接見(jiàn)文末)的文章。該篇文章在 2013 年沖上了Hacker News 的首頁(yè),并在/r/programming 上 收獲了超過(guò) 400 條評(píng)論。盡管我未留下當(dāng)時(shí)的分析數(shù)據(jù),但我推測(cè)這應(yīng)該是我最受關(guān)注的文章之一,而且這絕對(duì)是我第一次在寫(xiě)作中收獲大量反饋的難忘經(jīng)歷。
如今,十年過(guò)去了。在這段時(shí)間里,我從一個(gè)出于娛樂(lè)心態(tài)只是試驗(yàn) Go 語(yǔ)言的業(yè)余愛(ài)好者,轉(zhuǎn)變?yōu)橐幻麑?Go 列為主要編程語(yǔ)言的專業(yè)程序員。因此,我覺(jué)得現(xiàn)在回顧并分析我當(dāng)年的觀點(diǎn),探討我準(zhǔn)確預(yù)測(cè)了什么、什么事情發(fā)生了改變,以及我忽視和犯下了哪些錯(cuò)誤,這會(huì)是一次有趣的經(jīng)歷。你可以閱讀或重新閱讀原始博文,或者只需在這里閱讀我對(duì)過(guò)去的回顧,無(wú)需深入解析那篇文章。你只需要知道,正如它的標(biāo)題所示,我當(dāng)時(shí)把我對(duì) Go 語(yǔ)言的評(píng)價(jià)分為“優(yōu)點(diǎn)”、“缺點(diǎn)”和“平淡無(wú)奇之處”。
對(duì)于任何希望將本文提交至社交媒體的讀者,請(qǐng)注意,標(biāo)題中的引號(hào)非常重要。切勿刪除它們。
我的準(zhǔn)確預(yù)測(cè)
我仍然認(rèn)同我在”優(yōu)點(diǎn)”部分列出的大部分內(nèi)容。以下所有觀點(diǎn)我都依然認(rèn)為是對(duì)的:
-
Go 語(yǔ)言是為了在擁有現(xiàn)代版控系統(tǒng)的團(tuán)隊(duì)中開(kāi)發(fā)大型項(xiàng)目而設(shè)計(jì)的
通過(guò)大寫(xiě)字母來(lái)區(qū)分函數(shù)、方法、變量和字段的公有/私有狀態(tài)
將目錄作為包管理的基本單元
使用單一的二進(jìn)制文件進(jìn)行部署
go 工具運(yùn)行速度快,內(nèi)置了 go fmt、go doc 和 go test
使用后置類型樣式(var x int)而非前置類型樣式(int x)
有明確的變量聲明(相對(duì)于 Python 的 = 進(jìn)行隱式聲明)
Go Playground
邏輯類型名稱(如 int64,float32 等,而非 long 和 double)
提供三種基本數(shù)據(jù)類型:字符串、變長(zhǎng)數(shù)組和哈希映射
接口用于編譯時(shí)的鴨子類型 – 不支持繼承
至于其他部分,我們將在后續(xù)進(jìn)行討論。
發(fā)生的變化
過(guò)去十年中,Go 語(yǔ)言的最顯著變化無(wú)疑是引入了泛型。
在我之前的文章中,我把缺乏泛型列為了 Go 語(yǔ)言的一大弊端:
在 Go 代碼中,我們常會(huì)使用一些特殊的技巧,通過(guò)接口來(lái)避免使用泛型。但在某些情況下,你可能別無(wú)選擇,只能將函數(shù)復(fù)制粘貼多次,以針對(duì)不同類型進(jìn)行操作。如果你需要構(gòu)建自己的數(shù)據(jù)結(jié)構(gòu),你可能會(huì)選擇 interface {} 作為通用類型,但這會(huì)喪失編譯時(shí)的類型安全性。反之,如果你想實(shí)現(xiàn)一個(gè)通用的 sum 函數(shù),就沒(méi)有理想的解決方案。
在 2022 年 2 月發(fā)布的 Go 1.18 版本中,引入了泛型特性。這基本上解決了我以前的遇到問(wèn)題。例如,一個(gè)泛型的 sum 函數(shù)會(huì)像下面這樣:
type Numeric interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
~float64 | ~float32
}
func sum[N Numeric](vals ...N) N {
var total N = 0
for _, val := range vals {
total = val
}
return total
}
到目前為止,泛型的引入無(wú)疑是一項(xiàng)重大的改進(jìn)。
與 2013 年的 Go 語(yǔ)言相比,另一項(xiàng)重要變化是引入了 Go modules。我在過(guò)去的文章中提到,當(dāng)時(shí)的 GOPATH 系統(tǒng)是 Go 語(yǔ)言的一大優(yōu)點(diǎn):
如果你運(yùn)行 go get github.com/userA/project/,它將使用 git 從 github.com 下載項(xiàng)目,并自動(dòng)將其放置到正確的位置。如果該項(xiàng)目中包含行
import “bitbucket.com/userB/library”
,go 工具也能夠下載并安裝這個(gè)庫(kù)到指定位置。因此,Go 語(yǔ)言一舉具備了自身的優(yōu)雅打包解決方案和一個(gè)現(xiàn)代化的、去中心化的 CPAN 或 PyPI :你已經(jīng)在使用的版本控制系統(tǒng)!
Go modules 在原有的系統(tǒng)基礎(chǔ)上,增加了指定導(dǎo)入包以及 Go 本身的版本需求的功能。雖然在從 GOPATH 切換到 Go modules 的過(guò)程中出現(xiàn)了一些波折和不滿,但總的來(lái)說(shuō),過(guò)渡非常順利,就我個(gè)人而言,我并未遇到太多實(shí)際問(wèn)題。它的工作方式很有效,大多數(shù)時(shí)候你無(wú)需過(guò)多考慮它。
在我之前的文章中,我提到對(duì)于 Go 編譯器只產(chǎn)生錯(cuò)誤而不產(chǎn)生警告的情況我并未有太大的感觸。但過(guò)去十年中,這個(gè)問(wèn)題已經(jīng)演變?yōu)?go vet 可以產(chǎn)生低誤報(bào)率的錯(cuò)誤,而其他警告則可以通過(guò)各種 lint 工具產(chǎn)生。所以,從技術(shù)角度來(lái)說(shuō),編譯器依然沒(méi)有警告,但在實(shí)際使用中,Go 的生態(tài)系統(tǒng)確實(shí)提供了很多產(chǎn)生警告的途徑。這只是在你想要批評(píng) Go 時(shí),才會(huì)成為一個(gè)有趣的差異。
我的疏漏之處
在回顧我先前的文章時(shí),我注意到并未涉及聯(lián)合類型、交叉類型或者可選值這些概念。這反映出在過(guò)去的十年中,整個(gè)行業(yè)的狀況變化劇烈。在當(dāng)時(shí),和類型及可選值仍被視為學(xué)術(shù)性的特性,除了 Haskell 這樣的 ML 衍生語(yǔ)言,主流的 C 影響語(yǔ)言并沒(méi)有涵蓋這些特性。然而,自從 2014 年 Swift 和 2015 年 Rust 的誕生以來(lái), 所有的語(yǔ)言都開(kāi)始根據(jù)其是否解決了”空指針錯(cuò)誤”(被比喻為十億美元的錯(cuò)誤)進(jìn)行評(píng)價(jià)。
可惜的是,Go語(yǔ)言已經(jīng)有太多使用 nil 值的代碼,所以很難去掉 nil 值,以至于我們無(wú)法真正轉(zhuǎn)向可選類型,至少在我們所了解的 Go 語(yǔ)言中是如此。然而,有一個(gè)通過(guò)限制接口值來(lái)添加求和類型 的提法,我認(rèn)為這有很大的可能以某種形式實(shí)現(xiàn)。
值得一提的是,對(duì)語(yǔ)言的評(píng)價(jià)已經(jīng)發(fā)生了變化。我曾經(jīng)贊賞 Go 的類型推斷為技術(shù)進(jìn)步,而現(xiàn)在 Hacker News 的用戶則認(rèn)為 Go 的類型推斷與其他語(yǔ)言相比還比較弱。選擇一個(gè)不為人知的語(yǔ)言,或者堅(jiān)持足夠久,總會(huì)有一天你會(huì)成為別人詬病的目標(biāo)。
再回首過(guò)去,我發(fā)現(xiàn)我原文中還有一個(gè)疏漏是沒(méi)有提到 Go 1 保證。Go 1.0 發(fā)布時(shí),Go 團(tuán)隊(duì)對(duì)源代碼的兼容性做出了承諾。盡管一直都有警告、錯(cuò)誤和例外存在,但在大多數(shù)情況下,他們極大地遵守了這個(gè)承諾。公正地說(shuō),當(dāng)時(shí),Go 1.0.3 是最新的版本,因此我無(wú)法預(yù)見(jiàn) Go 1 的承諾將會(huì)持續(xù)十年以上,但我相信這對(duì) Go 成為今天的語(yǔ)言發(fā)揮了關(guān)鍵作用。在 Go 1.0 之前,Go 團(tuán)隊(duì)經(jīng)常對(duì)語(yǔ)言或標(biāo)準(zhǔn)庫(kù)做出改變,為了跟上新標(biāo)準(zhǔn),需要在代碼庫(kù)上運(yùn)行 go fix。然而,自那時(shí)以來(lái),只要你寫(xiě)的是 Go 程序,使用的是標(biāo)準(zhǔn)庫(kù),并且沒(méi)有依賴于不安全的特性或者安全漏洞,你就能保證你的代碼一直正常運(yùn)行。
相比其他生態(tài)系統(tǒng),這是一股真正的清新之風(fēng),作為開(kāi)發(fā)人員,這是我最喜歡的事情之一。在其他編程語(yǔ)言中,升級(jí)到一個(gè)新版本(即使是一個(gè)次要版本),往往讓人感到擔(dān)憂,擔(dān)心會(huì)有一些意想不到的問(wèn)題出現(xiàn)。即使在升級(jí)過(guò)程中提前通過(guò)棄用警告聲明了問(wèn)題,仍然需要花時(shí)間來(lái)修復(fù)相關(guān)問(wèn)題。但是使用Go,我不會(huì)擔(dān)心這些。GO 語(yǔ)言團(tuán)隊(duì)非常為開(kāi)發(fā)者著想。
我的觀點(diǎn)更新
總體而言,我認(rèn)為我之前的博文質(zhì)量不錯(cuò),沒(méi)有什么明顯的錯(cuò)誤。不過(guò),雖然并不完全否定我之前的有些看法,但我現(xiàn)在有了更深入的理解。
具體而言,在我描述的“優(yōu)點(diǎn)”部分,沒(méi)有什么真正的不足之處,但回顧過(guò)去,我對(duì)并發(fā)帶來(lái)的權(quán)衡有了更深的認(rèn)識(shí)。
我曾寫(xiě)到:
Go 的并發(fā)處理方式,就如同你在剛開(kāi)始學(xué)習(xí)并發(fā)時(shí)所設(shè)想的那樣,非常易于理解和使用。如果你想并發(fā)地運(yùn)行一個(gè)函數(shù),只需要使用 go function(arguments)。如果你需要讓函數(shù)間進(jìn)行通信,你可以使用通道,這些通道默認(rèn)會(huì)同步執(zhí)行,即在兩端都準(zhǔn)備就緒前,會(huì)暫停執(zhí)行。
這個(gè)觀點(diǎn)仍然是正確的,我依然認(rèn)為在 Go 中處理并發(fā)比在 Python 中要簡(jiǎn)單得多。(順便說(shuō)一句,我寫(xiě)下這些觀點(diǎn)是在 JavaScript 添加了 Promise 和 await 之前。)然而,類型系統(tǒng)并不能阻止你創(chuàng)建數(shù)據(jù)競(jìng)爭(zhēng),因此在測(cè)試過(guò)程中你必須在依賴數(shù)據(jù)競(jìng)爭(zhēng)檢測(cè)器,如果你在不遵循公認(rèn)的模式的情況下直接使用通道創(chuàng)建結(jié)構(gòu)化并發(fā),這會(huì)導(dǎo)致代碼混亂。這是一種權(quán)衡,Go 給你充足的自由以至于可能自我陷入困境,但在大多數(shù)時(shí)候,當(dāng)你只是編寫(xiě)網(wǎng)絡(luò)服務(wù)器或類似的應(yīng)用時(shí),你可以獲得并發(fā)的大部分好處,而不會(huì)遇到太多的麻煩。
就我列出的“缺點(diǎn)”部分來(lái)說(shuō),大部分實(shí)際上并未給我?guī)?lái)太大問(wèn)題。我不確定為何我會(huì)過(guò)度擔(dān)憂字符串類型無(wú)法定義方法。腳本無(wú)法以 #! 開(kāi)頭在實(shí)踐中其實(shí)并不重要。Go 的語(yǔ)言設(shè)計(jì)并非完全遵循 DRY (Don’t repeat yourself,不要重復(fù)你自己)原則,但這更多的是一種權(quán)衡,而非“缺點(diǎn)”。
雖然缺乏泛型有時(shí)會(huì)導(dǎo)致問(wèn)題,但通常有明確的解決辦法,例如使用動(dòng)態(tài)類型,使用反射,或者編寫(xiě)一個(gè)代碼生成器。我很高興 Go 現(xiàn)在引入了泛型,但事實(shí)上,沒(méi)有泛型時(shí)我們只會(huì)偶爾遇到真正的問(wèn)題。我非常期待看到泛型如何影響 Go 的未來(lái)發(fā)展,尤其是在 Go 團(tuán)隊(duì)正在研究迭代器的情況下,但我確實(shí)有些擔(dān)心可能會(huì)出現(xiàn)“泛型的濫用”,即在普通接口已經(jīng)能夠很好工作的地方過(guò)度使用泛型。我們將拭目以待。
我在“無(wú)所謂”的部分列出的大部分事項(xiàng),實(shí)際上更多的是權(quán)衡,然而事后看來(lái),我認(rèn)為 Go 在它所選擇的設(shè)計(jì)范圍內(nèi)做出了更好的決定。沒(méi)有異常機(jī)制是一種權(quán)衡,雖然我可能希望 Go 有像 Zig 的 try 和 errdefer 那樣的功能,但實(shí)際上,當(dāng)前的方式是可行的。盡管使用 if err != nil 是目前為止最差的選擇,除去所有其他不定期試驗(yàn)的系統(tǒng),但事實(shí)證明,它能促使用戶代碼有用的演變。
如 Matklad 在一條最近的評(píng)論中所說(shuō),
看來(lái)在錯(cuò)誤處理上,我們(開(kāi)發(fā)者社區(qū))大致達(dá)成了共識(shí)。Midori、Go、Rust、Swift、Zig 在設(shè)計(jì)上有著相似之處,這并非完全是檢查異常,但卻非常接近。
1、有一種標(biāo)記函數(shù)可能會(huì)失敗的方式。這通常是返回類型的屬性,而不是函數(shù)本身的屬性(Rust 中的 Result,Go 中的錯(cuò)誤對(duì),Zig 中的 ! 類型,以及 Midori 和 Swift 中的 bare throws decl)
2、我們不僅標(biāo)記拋出異常的函數(shù)聲明,還會(huì)標(biāo)記調(diào)用處(Midori、Swift、Zig 中的 try,Rust 中的 ?,Go 中的 if err != nil)。
3、默認(rèn)存在一個(gè) AnyError 類型(Go 中的 error,Swift 中的 Error,Rust 中的 anyhow,Zig 中的 anyerror)。一般來(lái)說(shuō),區(qū)分是否有錯(cuò)誤的價(jià)值,大于詳盡地指定錯(cuò)誤集合。
這種觀點(diǎn)對(duì)我來(lái)說(shuō)是合理的。Go 的錯(cuò)誤處理相比其他語(yǔ)言更為繁瑣,但從結(jié)構(gòu)上來(lái)看,它們?cè)诘讓佑性S多共同之處。
我曾把 Go 缺乏操作符重載、函數(shù)/方法重載或關(guān)鍵字參數(shù)等特性歸入“無(wú)所謂”的部分,但現(xiàn)在我對(duì)這種狀態(tài)感到非常滿意。我希望 Go 有操作符重載的唯一情況是 big.Int ,我希望有一天這些特性會(huì)被添加到語(yǔ)言本身中。關(guān)鍵字參數(shù)可能是好的,但實(shí)際上,結(jié)構(gòu)體就夠用了,如果有真正棘手的情況,總是有 方法鏈的構(gòu)建器可用。
總結(jié)
在撰寫(xiě)這篇文章前, 我原以為讀者們會(huì)關(guān)注我對(duì)面向?qū)ο缶幊痰呐u(píng),然而,實(shí)際上他們更在意的是我用“白癡”一詞描述爭(zhēng)論公有/私有字段問(wèn)題的人。
我在文章中提出的最大疑問(wèn)可能是 Go 語(yǔ)言對(duì)接口的運(yùn)用以及繼承特性的缺失。我認(rèn)為這是一個(gè)好主意,但也歡迎實(shí)踐的檢驗(yàn),并期待聽(tīng)到不同的觀點(diǎn)。Hynek Schlawack 在 2021 年發(fā)表的一篇極佳的文章解釋了為什么接口的運(yùn)用以及沒(méi)有繼承可以被看作是 Go 的優(yōu)秀設(shè)計(jì)選擇。簡(jiǎn)單來(lái)說(shuō),只有在子類覆寫(xiě)超類方法的情況下,繼承才有意義。在這種情況下,Go 的類型嵌入表現(xiàn)得十分出色。因此,我終于激起了我期待已久的討論,盡管這花了大約八年的時(shí)間。
直到 2019 年,Dan Abramov 才對(duì) Hacker News 的寫(xiě)作經(jīng)驗(yàn)進(jìn)行了深入的解讀:
恭喜你!
你的項(xiàng)目成為了熱門(mén)新聞聚合器的頭條。社區(qū)里的一些知名人士也在推特上提到了它。他們?cè)谡f(shuō)些什么?
你感到心情沉重。
并不是說(shuō)人們不喜歡這個(gè)項(xiàng)目。你清楚項(xiàng)目存在權(quán)衡,也期待人們會(huì)對(duì)此進(jìn)行討論。但是事情并未如預(yù)期發(fā)生。
然而,評(píng)論在很大程度上并不關(guān)心你的想法。
最熱門(mén)的評(píng)論主題是圍繞 README 示例中的編碼風(fēng)格。它演變成了一個(gè)關(guān)于縮進(jìn)的爭(zhēng)論,有一百多條回復(fù),并對(duì)不同的編程語(yǔ)言如何處理格式進(jìn)行了簡(jiǎn)短的歷史回顧。其中必然會(huì)提到 gofmt 和 Python。你使用過(guò) Prettier 嗎?
…
你感到困惑,關(guān)閉了標(biāo)簽頁(yè)。
發(fā)生了什么?
也許是你的想法簡(jiǎn)單地不像你想象的那樣有趣。也可能是你對(duì)偶然訪問(wèn)的人解釋得不夠好。
但是,你可能沒(méi)有得到相關(guān)反饋的另一個(gè)原因。
我們更偏向于探討那些相對(duì)容易討論的話題。
我已經(jīng)接受了這樣一個(gè)事實(shí):論壇上的人們(包括我自己)更容易關(guān)注自己已經(jīng)想到的事情,而非文章所討論的主題。這就是現(xiàn)實(shí),短期內(nèi)恐怕無(wú)法改變。
我認(rèn)為 Rachel 的 Run XOR Use 規(guī)則 (要么使用一個(gè)聊天窗口或留言板,但不能同時(shí)做兩者。這是為了避免沖突和分散注意力。)同樣適用于撰寫(xiě)和討論博客文章。如果你發(fā)布了文章,你必須預(yù)備好討論會(huì)擴(kuò)展到你自己都未曾預(yù)見(jiàn)的領(lǐng)域。
對(duì)于 Go 語(yǔ)言,我現(xiàn)在的滿意度超過(guò)了以往的任何時(shí)期。雖然它的速度并不如 Rust,但已經(jīng)超過(guò)了我的需求,同時(shí)并無(wú)過(guò)度的模板代碼或抽象概念誘惑。我認(rèn)為 GO 語(yǔ)言團(tuán)隊(duì)具有良好的洞察力,他們總是穩(wěn)健地向正確的方向前進(jìn)。我期待看到它未來(lái)的發(fā)展。
預(yù)測(cè)總是很難的,尤其是對(duì)于未來(lái)的事物。十年后我還會(huì)使用 Go 嗎?我無(wú)法確定。預(yù)期中的十年總似乎比回顧中的時(shí)間要長(zhǎng)。也許那時(shí)我們只是在檢查由 AI 生成的代碼的輸出,雖然這聽(tīng)起來(lái)有些消極。但至少現(xiàn)在,我樂(lè)意將它作為我的主要編程語(yǔ)言。
以下是那篇文章的原始結(jié)論,以及我在 2023 年的更新:
Go 真的很棒,它已經(jīng)成為我的日常語(yǔ)言(它曾經(jīng)是 Python ),而且它絕對(duì)是一種趣味十足的語(yǔ)言,非常適合處理大型項(xiàng)目。如果你有興趣學(xué)習(xí) Go,我建議學(xué)習(xí)下這個(gè)簡(jiǎn)單的教程,然后在將測(cè)試程序輸入到 Playground 中運(yùn)行,并且認(rèn)真學(xué)習(xí) GO 語(yǔ)言規(guī)范。該規(guī)范簡(jiǎn)潔易讀,是學(xué)習(xí) Go 非常好的學(xué)習(xí)材料。
讓我們?cè)?2033 年再會(huì),屆時(shí)我們將會(huì)在 “““Go 語(yǔ)言:優(yōu)點(diǎn)、缺點(diǎn)和平淡無(wú)奇之處” 十年”十年” 中相見(jiàn)。
你也正在使用 GO 語(yǔ)言編程嗎?你認(rèn)同作者的說(shuō)法嗎?你對(duì) GO 語(yǔ)言怎么看?歡迎在評(píng)論區(qū)討論。
參考鏈接:
-
Go 語(yǔ)言:優(yōu)點(diǎn)、缺點(diǎn)和平淡無(wú)奇之處:https://blog.carlmjohnson.net/post/google-go-the-good-the-bad-and-the-meh/
Hacker News:https://news.ycombinator.com/item?id=5200916
John Carmack 是否閱讀過(guò)這篇文章:https://twitter.com/ID_AA_Carmack/status/1293311943995002881
原始博文:https://blog.carlmjohnson.net/post/google-go-the-good-the-bad-and-the-meh/
Go Playground:https://go.dev/play/
Go 1.18 版本中:https://blog.carlmjohnson.net/post/2021/golang-118-minor-features/
下面這樣:https://go.dev/play/p/R-QDDqcp3w9
十億美元的錯(cuò)誤:https://en.wikipedia.org/wiki/_pointer#History
通過(guò)限制接口值來(lái)添加求和類型:https://github.com/golang/go/issues/57644
選擇一個(gè)不為人知的語(yǔ)言,或者堅(jiān)持足夠久,總會(huì)有一天你會(huì)成為別人詬病的目標(biāo):https://www.stroustrup.com/quotes.html
Go 1 保證:https://go.dev/doc/go1compat
Go 1.0.3 是最新的版本:https://go.dev/doc/devel/release#go1
公認(rèn)的模式:https://blog.carlmjohnson.net/post/share-memory-by-communicating/
結(jié)構(gòu)化并發(fā):https://github.com/carlmjohnson/flowmatic
導(dǎo)致代碼混亂:https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/
實(shí)踐中其實(shí)并不重要:https://github.com/carlmjohnson/go-run
DRY:https://en.wikipedia.org/wiki/Don’t_repeat_yourself
用戶代碼有用的演變:https://blog.carlmjohnson.net/post/2020/working-with-errors-as/
Matklad:https://matklad.github.io/
一條最近的評(píng)論:https://lobste.rs/s/aocv9o/trouble_with_checked_exceptions_2003#c_bsxqyu
big.Int:https://pkg.go.dev/math/big#Int
添加到語(yǔ)言本身中:https://github.com/golang/go/issues/19624
方法鏈的構(gòu)建器:https://blog.carlmjohnson.net/post/2021/requests-golang-http-client/
這篇文章:https://blog.carlmjohnson.net/post/google-go-the-good-the-bad-and-the-meh/
一篇極佳的文章:https://hynek.me/articles/python-subclassing-redux/
深入的解讀:https://overreacted.io/name-it-and-they-will-come/
Run XOR Use 規(guī)則:https://rachelbythebay.com/w/2021/05/26/irc/
雖然這聽(tīng)起來(lái)有些消極:https://blog.carlmjohnson.net/post/2016-04-09-alphago-and-our-dystopian-ai-future/
那篇文章:https://blog.carlmjohnson.net/post/google-go-the-good-the-bad-and-the-meh/
學(xué)習(xí)下這個(gè)簡(jiǎn)單的教程:http://tour.golang.org/
Playground:http://play.golang.org/
GO 語(yǔ)言規(guī)范:http://golang.org/ref/spec