Go 之父:聊聊我眼中的 Go 語言和環境

語言: CN / TW / HK

大家好,我是煎魚。

之前春節假期,在家閉關多日。看到了在 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 的核心精神和理念。

一些交流

  1. 泛型:之所以一開始沒有放進特性裏,是因為不知道怎麼會對他感到不舒服,不確定性極高。但經過 10+ 年的努力,現在已經有了一個基本設計和模型,很有可能會打破一切,Rob Pike 也非常好奇後續的效果。

  2. 聲明變量:當前聲明的方式比較多,甚至有想砍掉一些。

  3. Channel:認真的嘗試過把 channel 和 network 協作,但是一直沒有找到好的辦法。

  4. GOPATH:Go1.14 以前,會是 GOPATH 的原因,是因為幾個開發者確實是在 Google 工作,Google 採取的是 Menorepo 的模式,沒有分佈式模型的原生態。

參考

  • The Go Programming Language and Environment

關注煎魚,獲取業內第一手消息和知識 :point_down:

你好,我是煎魚, 出版過 Go 暢銷書《Go 語言編程之旅》,再到獲得 GOP(Go 領域最有觀點專家)榮譽, 點擊藍字查看我的出書之路

日常分享高質量文章,輸出 Go 面試、工作經驗、架構設計, 加微信拉讀者交流羣,和大家交流!