Go 之父:聊聊我眼中的 Go 語言和環境
大家好,我是煎魚。
之前春節假期,在家閉關多日。看到了在 2021 年 6 月 Go 語言之父 Rob Pike 在 UNSW Computing(悉尼新南威爾士大學計算機)組織的分享會議,介紹了他對現在 Go 編程語言和環境的一些看法。
今天煎魚結合大佬的演講《The Go Programming Language and Environment》和一點個人理解給大家分享一波,包含 Go 發展、生態、看法等多方面知識。
Go 怎麼樣
Rob Pike 表示其實 Go 目前還不能算做主流語言,但是在全世界的影響力和發展都大大的超出了預期。

像在國內的我們,能夠很明顯感知到,Go 在近 3~5 年的用户羣體不斷增大。我早年在 Segmentfault 上發文章,過了 1~2 周,我的 Go 文章,也還在第一頁的前幾位,發文的人比較稀少,但現在人非常多了。
大家會發現,Go 並不是那種非常 “有趣” 的語言,在技術上(語言理論、設計)幾乎沒有什麼大進步。當然,這也不是 Go 核心團隊的設計目標。
但就是這麼一門語言,他主導了大部分 CNCF 中的項目,例如:K8s、Docker 等,特別牛。 Go 是雲基礎設施的語言,這是怎麼發生的 ?
Go 為什麼成功
Go 從一門無人問津的語言,到現在承擔了各雲基礎設施的核心,變得很重要,也是一種成功實踐。
Rob Pike 認為成功的因素有如下:

Rob Pike 在 Google 工作時,當時遇到了上述 PPT 截圖中的許多問題,像是:軟件規模、長期兼容性、應用構建緩慢等許多方面。
核心觀點: 一門編程語言的成功取決於其他很多方面,Go 語言是面向軟件開發的,而不僅僅只是編程 。
為此,Go 就是為了解決軟件開發而生,而非只是編程,這是成功的關鍵因素。
Go 要解決的難題
他們遇到的一個大問題就是 Scale(規模),規模又分為了 3 大塊問題。
分別是:
-
併發(Concurrency)。
-
工程(Engineering)。
-
依賴(Dependencies)。
併發
在 2007 年,軟件規模的擴大的情況下,Google 的生產集羣出現了多核 CPU。
當時沒有成熟的主流語言可以將多核全部正確使用,導致 Google 即使擁有這些龐大的計算集羣,硬件資源的利用率也非常低。

線程模型和庫很神祕,很複雜,很困難。由於環境的要求,生產代碼中不被允許使用線程,而是啟動多個二進制文件。
工程
Google 在軟件開發上採取的是 Menorepo 的單倉庫分包的模式,因此會有成千上萬的程序員在同一個代碼庫中工作,每天都有數不清的變化。

但是當時用的都是 C++、Java 等這類語言,太難自動化和分析,很難帶來工具的幫助。
依賴
軟件規模下的大量依賴,給 Google 帶來了很大的麻煩。

Java 和 C++的開發速度很慢,C++ 代碼的每一個字節都變成了 2000 個字節。
沒有辦法知道依賴性是否是必要的,感覺是很糟糕的。
Go 初始特性
Go 的大部分核心特性,其實是大佬們在 2007 年 9 月的一個下午,在白板上畫了草圖和討論出的。
如下:

-
語法、語義。
-
併發性。
-
封裝。
-
垃圾回收。
-
工具化。
-
自動化,包括格式化。
接口化
在日常的 Go 程序(標準庫、第三方庫、應用程序等)中,存在着許多微小的接口,可以讓我們做許多的事情,像是寫入圖片都可以寫入到任意地方。

這種接口化,也就是常説的鴨子類型(duck typing):像鴨子走路,像鴨子叫(長得像鴨子),那麼就是鴨子。
構成了 Go 的應用文化。
類型支持
在類型設計上,Go 與其他編程語言有着很根本的一個差異,那就是不能不同類型混合在一起做運算操作:

要跨類型的話,必須做顯示轉換,不存在明確的隱式轉換。
併發
Go 要用協程做併發、並行等動作,非常方便,不需要幾行代碼。
普通的工程師都能上手:


這是一個很重要的殺手級特性和賣點。
安全性
在設計時,Go 對安全性考慮了許多。一般來講,是沒法做一些不安全的事情,但硬要做,就必須引用 unsafe 的庫:

使用 Go 會比 C/C++ 簡單許多,既安全又省心。如果出現了 unsafe 的引用,就能明確知道這個程序是 “不安全” 的。
完整性
Go 基於前面所提到的接口化,面向網絡、密碼學、文本處理、格式化 IO 等實現了一系列的核心基礎庫:

主體指的是 Go 把常用的都覆蓋全了,非常高效全面。
一致性
跨系統的編譯,只需要稍微調整 2 個環境變量,就可以在 A 系統打出 B 系統能運行的二進制文件,並且行為一致,也不用擔心垃圾回收。

Rob Pike 還介紹了自己平時都是在 MacOS 下開發,會經常打一個 Linux 的二進制文件部署到服務器上去運行,非常方便。
兼容性
Go 在 2012 年發佈 Go1.0 起,就起草了一份 Go1 兼容性保障的文檔,以此作為對用户的承諾。將在 Go1 內不會出現破壞性修改,你 10 年前的代碼能跑,10 年後也能跑,非常舒服。

從現在來看,也是做到了。
開發工具
配套的 Go 開發者工具,是具有標準化的,不像某些語言左一個右一個的,非常混亂。

Go 工具鏈都是 go build、go fmt 等模式。
依賴庫
官方有大量的標準庫提供,用户可以自定義第三方庫。依賴的管理方式是非集中式的,可以在每個人的 URL(例如:GitHub 等),不存在搶佔註冊的風險。

有一點遺憾的是,在早期庫依賴時,理論上但就應該包含模塊的依賴管理。但當時沒有做到,現在有了,也算是 OK 了。
主題
如果希望把 Go 這門語言的生態系統做起來,就要在社區中運轉,能夠讓其他人做出貢獻。

這裏最常見的就是 IDE 的各種 Go 插件,以及平時我們正在使用的第三方庫,他人開發的工具等,都可以拿來就用。
文化
Go 社區文化的構建,本質上 Go 現在作為雲原生應用的基礎,構建了現代的雲環境,是由社區主動發起的。

共同維護更美好的願景,一種安全、兼容、可移植性和可讀性的文化。
總結
在設計一門語言時,不單單只是設計他,必須要培養他,把其身邊的生態系統都做起來,讓他變得繁榮。

像是 Go,快速、高效、可移植性、部署簡單、長期兼容、簡單抽象、好用工具、容易測試、容易自動化、很好用的依賴庫等。這些東西共同構成了他的文化,也會使他做的更好。
Rob Pike 表示: Go 是關於軟件開發的,而不僅僅是編程 ,這是 Go 的核心精神和理念。
一些交流
-
泛型:之所以一開始沒有放進特性裏,是因為不知道怎麼會對他感到不舒服,不確定性極高。但經過 10+ 年的努力,現在已經有了一個基本設計和模型,很有可能會打破一切,Rob Pike 也非常好奇後續的效果。
-
聲明變量:當前聲明的方式比較多,甚至有想砍掉一些。
-
Channel:認真的嘗試過把 channel 和 network 協作,但是一直沒有找到好的辦法。
-
GOPATH:Go1.14 以前,會是 GOPATH 的原因,是因為幾個開發者確實是在 Google 工作,Google 採取的是 Menorepo 的模式,沒有分佈式模型的原生態。
參考
-
The Go Programming Language and Environment
關注煎魚,獲取業內第一手消息和知識 :point_down:
你好,我是煎魚, 出版過 Go 暢銷書《Go 語言編程之旅》,再到獲得 GOP(Go 領域最有觀點專家)榮譽, 點擊藍字查看我的出書之路 。
日常分享高質量文章,輸出 Go 面試、工作經驗、架構設計, 加微信拉讀者交流羣,和大家交流!
- Go 代碼風格沒人喜歡?不對,Gofmt 是所有人的最愛...
- 10 張圖解|高併發分佈式架構演進
- Go 只會 if err != nil?這是不對的,分享這些優雅的處理姿勢給你!
- 中美程序員不完全對比
- Go 常量只支持基本數據類型?為什麼?社區撕了 9 年了...
- Go1.19 那些事:國產芯片、內存模型等新特性,你知道多少?
- 有人問你後端面試考哪些?把這篇扔給他!
- Go 內聯優化:如何讓我們的程序更快?
- goto 語句讓 Go 代碼變成意大利麪條?
- Go 錯誤處理中再套個娃,能解決煩惱不?
- 10 條 Go 官方諺語,你知道幾條?
- 新提案:創建 Go 簡單類型的指針表達式
- 為什麼 Go 語言能在中國這麼火?
- 好物分享:快速找到 Goroutine 泄露的地方
- 新提案:增加標準庫 Context 的取消 API
- Go 之父:聊聊我眼中的 Go 語言和環境
- 太瘋狂了,Go 程序説 nil 不是 nil...
- Go 返回值命名還有存在的必要嗎?
- Go 要違背初心嗎?新提案:手動管理內存
- 開啟 Go 泛型時代:第三方泛型庫分享