自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go語言之父:開源14年,Go不止是編程語言,究竟做對了哪些?

譯文
開發(fā) 前端
推出 14 年后,我們最后成功了。總的來說,很大程度上是因為最初把設(shè)計和開發(fā) Go 作為一種編寫軟件的方式(而不僅僅是作為一種編程語言)這項決定,才帶領(lǐng)我們來到了這樣一個新地方。

編譯 | 言征

作者 | Rob Pike

提及編程語言,2023 年,除了老牌的 C++ 和新晉之秀 Rust 熱度最高之外,就要數(shù) Go 了。 從 2009 年由 C 語言獲取靈感而發(fā)布,到如今風(fēng)靡已久的高性能語言,Go 已經(jīng)走過了 14 個年頭。

“Go是一個項目,不只是一門語言。我們最初的目標(biāo)不是創(chuàng)建一種新的編程語言,而是創(chuàng)建一種更好的軟件編寫方式。”

2023 年 11 月 10 日是 Go 作為開源項目推出 14 周年。Go語言之父 Rob Pike 在在悉尼 GopherConAU 會議上進(jìn)行了一場耐人尋味的演講。Go走到今天,做對了什么?做錯了什么?這里總結(jié)在此,以饗諸君。

一、我們做對了什么,做錯了什么 

今天是 2023 年 11 月 10 日,Go 作為開源項目推出 14 周年。2009年的這天,加州時間下午 3 點(diǎn)(如果沒記錯的話),Ken Thompson、Robert Griesemer、Russ Cox、Ian Taylor、Adam Langley、Jini Kim 和我滿懷期待地看著網(wǎng)站上線,全世界都知道了我們在做什么。

圖片圖片

Go是一個項目,不只是一門語言。

即使是最成功的項目 ,經(jīng)過反思,也有一些可以做得更好的地方。當(dāng)然 ,事后看來,這些事情似乎是他們成功的關(guān)鍵。

這些因素正是我們想要解決的:構(gòu)建現(xiàn)代服務(wù)器軟件的復(fù)雜性:控制依賴性、與人員不斷變化的大型團(tuán)隊一起編程、易于維護(hù)、高效測試、多核 CPU 和網(wǎng)絡(luò)的有效使用等等。 

根據(jù)大家的反饋看,認(rèn)為 Go 做錯的事情都在語言層面, 而其實Go做對的事情,都在更大的故事中,即圍繞語言的周邊工具和生態(tài), 比如 gofmt 以及部署和測試。這說明Go成員們做對了。 

二、Go哪里做對了?

Go為什么會取得現(xiàn)在的成功?總結(jié)了有以下幾點(diǎn)。每一個都至關(guān)重要。

1.規(guī)范說明

我們從正式的規(guī)范開始。這不僅可以在編寫編譯器時鎖定行為,還可以使 多個實現(xiàn)共存并就該行為達(dá)成一致。編譯器本身并不是一個規(guī)范。您測試編譯器的依據(jù)是什么?

2.多種實現(xiàn)方式

有多個編譯器,它們都實現(xiàn)相同的規(guī)范。有了規(guī)范就可以更容易地實現(xiàn)這一點(diǎn)。

有一天,伊恩·泰勒(Ian Taylor)發(fā)郵件通知我們,在閱讀了我們的規(guī)范草案后,他自己編寫了一個編譯器,這讓我們感到驚訝。

圖片圖片

 

我的一位同事向我指出了 http://.../go_lang.html 。 它看起來是一種有趣的語言,我拼湊了一個 gcc前端。 當(dāng)然,它缺少很多功能,但它確實在網(wǎng)頁上編譯了素數(shù)篩代碼。

這是令人興奮的,但更多的事情也隨之而來,所有這些都因正式規(guī)范的存在而成為可能。

擁有多個編譯器幫助我們改進(jìn)了語言并完善了規(guī)范,并為那些不太喜歡我們類似 Plan-9 的業(yè)務(wù)方式的其他人提供了替代環(huán)境。

如今有很多兼容的實現(xiàn),這很棒。

3.便攜性

我們使交叉編譯變得微不足道,這使得程序員可以在他們喜歡的任何平臺上工作,并交付到任何需要的平臺。 人們很容易將編譯器視為是與運(yùn)行的本機(jī)是原生的。Go可以打破這個假設(shè),對許多開發(fā)者來說都是新聞。

圖片

4.兼容性

我們努力使語言成型1.0 版本,然后通過兼容性保證將其鎖定。Go的受歡迎程度已經(jīng)很高,在一個幾乎沒有其他東西是穩(wěn)定的世界中,不用擔(dān)心新的 Go 版本會破壞你的項目,是最讓人心安的。當(dāng)然,很多其他項目不會這么做,因為維護(hù)強(qiáng)大的兼容性是需要成本的。

圖片圖片

5.庫

庫的發(fā)展有點(diǎn)偶然。一開始可以安裝 Go 代碼的地方非常貧瘠,但這樣一個可靠、制作精良的庫的存在,其中包含編寫 21 世紀(jì)服務(wù)器代碼所需的大部分內(nèi)容,是一項重要資產(chǎn)。它讓社區(qū)所有人都使用同一個工具包,直到我們有足夠的經(jīng)驗來了解還應(yīng)該提供什么。這非常有效,有助于防止變體庫的出現(xiàn),有助于統(tǒng)一社區(qū)。

6.工具

我們確保該語言易于解析,從而支持工具構(gòu)建。起初我們認(rèn)為我們需要一個適用于 Go 的 IDE,但擁有簡單的工具反而會意味著,IDE 遲早將出現(xiàn)在 Go 上。這些工具和 gopls 一起就做到了,而且他們非常棒。

我們還為編譯器提供了一套輔助工具,例如 自動化測試、覆蓋率和代碼審查。當(dāng)然還有 go 命令,它集成了整個構(gòu)建過程,并且是許多項目構(gòu)建和維護(hù) Go 代碼所需的全部內(nèi)容。

此外,Go 獲得了快速構(gòu)建的聲譽(yù)。

7.gofmt 

我將 gofmt 作為一個單獨(dú)的項目從工具中拿出來,因為 它不僅給Go,而且給整個編程社區(qū)上都帶來了新的活力。在 Robert 編寫 gofmt 之前,自動格式化程序的質(zhì)量不高,因此大多未使用。

Gofmt 表明它可以做得很好,今天幾乎每種值得使用的語言都有一個標(biāo)準(zhǔn)格式化程序。不爭論空格和換行符所節(jié)省的時間值得花在定義標(biāo)準(zhǔn)格式和編寫這段相當(dāng)困難的代碼以實現(xiàn)自動化上的所有時間。

此外,gofmt 還使無數(shù)其他工具成為可能,例如簡化器、分析器甚至代碼覆蓋率工具。因為 gofmt 的內(nèi)容成為了任何人都可以使用的庫,所以您可以解析程序、編輯 AST,然后打印字節(jié)完美的輸出,供人類和機(jī)器使用。

三、Go 哪里做錯了?

1.并發(fā)成就了Go,但Go有責(zé)任做好指導(dǎo) 

并發(fā)性成就了 Go,它讓Go看起來像是一種新事物。Go 對并發(fā)的支持是一個主要的吸引因素,提高了Go的早期采用率。同時,Go 的誕生在一定程度上讓并發(fā)編程成為了一種主流思想,它讓編程世界相信并發(fā)是一個強(qiáng)大的工具(特別是在多核網(wǎng)絡(luò)世界中)方面發(fā)揮了重要作用,并且它可以比 pthread 做得更好?,F(xiàn)在大多數(shù)主流語言都對并發(fā)有很好的支持。

更有意思的是,Go 版本的并發(fā),非常新穎。沒有協(xié)程,沒有任務(wù),沒有線程,沒有名稱,只有 goroutine。我們發(fā)明了“goroutine”這個詞,因為沒有合適的現(xiàn)有術(shù)語。直到今天我還是希望 Unix 的拼寫命令能夠?qū)W會它。

問題來了,這就是我們犯了兩個重大錯誤的地方。 

首先,并發(fā)很有趣,但我們想到的用例主要是服務(wù)器的東西,也就意味著在 net/http 等關(guān)鍵庫中完成,而不是在每個程序中隨處可見。因此,當(dāng)許多程序員使用它時,他們很難弄清楚它如何真正幫助到他們。

我們應(yīng)該預(yù)先解釋聲明一下,該語言中的并發(fā)支持真正帶來的是更簡單的服務(wù)器軟件。這個問題就在于許多人都認(rèn)為重要,但并不是對所有嘗試過 Go 的人來說都很重要?!叭狈憫?yīng)的指導(dǎo)是我們的責(zé)任?!?nbsp;   

第二點(diǎn)就是,我們花了太長時間來澄清并行性(支持多核機(jī)器上并行的多個計算)和并發(fā)性(這是一種構(gòu)造代碼以實現(xiàn)這一點(diǎn)的方法)之間的區(qū)別。

無數(shù)程序員試圖通過使用 goroutine 并行化來提高代碼速度,但常常對由此產(chǎn)生的速度減慢感到困惑。如果底層問題本質(zhì)上是并行的,比如處理 HTTP 請求,那么并行代碼只會在并行化時運(yùn)行得更快。我們在解釋這一點(diǎn)上做得很糟糕,結(jié)果讓許多程序員感到困惑,并可能趕走了一些程序員。

為了解決這個問題,2012 年,我在 Heroku 的 Waza 開發(fā)者大會上發(fā)表了演講 ,名為“并發(fā)不是并行”。這是一個有趣的演講,但應(yīng)該早點(diǎn)發(fā)生。

對此表示歉意。但好處仍然存在:Go 幫助普及了并發(fā)性作為構(gòu)建服務(wù)器軟件的一種方式。

2.接口

我認(rèn)為接口是 Go 中設(shè)計得最好的東西之一。而且很明顯,接口和并發(fā)性是 Go 中的一個獨(dú)特的想法。它們是 Go 對面向?qū)ο笤O(shè)計的回答,采用原始的、以行為為中心的風(fēng)格,盡管新來者不斷推動結(jié)構(gòu)體承載這種負(fù)載。

使接口動態(tài)化,無需提前宣布哪些類型實現(xiàn)它們,這困擾了一些早期的批評者,并且仍然激怒了一些人,但這對于 Go 所培育的編程風(fēng)格很重要。標(biāo)準(zhǔn)庫的大部分內(nèi)容都是 建立在它們的基礎(chǔ)上的,而更廣泛的主題(例如測試 和管理依賴項)在很大程度上依賴于它們慷慨的“ 歡迎所有人”的性質(zhì)。  

這里有一個故事要講。在羅伯特和我辦公室的那個著名的第一天,我們問了一個問題:如何處理多態(tài)性。Ken 和我從 C 語言中知道 qsort 可以作為一個困難的測試用例,因此我們?nèi)齻€開始討論我們的“胚胎語言”如何實現(xiàn)類型安全的排序例程。

羅伯特和我?guī)缀跬瑫r提出了相同的想法:使用類型上的方法來提供排序所需的操作。這個概念很快就發(fā)展成為這樣的想法:值類型具有行為,定義為方法,并且方法集可以提供函數(shù)可以操作的接口。Go 的接口幾乎立刻就出現(xiàn)了。 

這是經(jīng)常被忽視的事情:Go 的排序是作為在接口上運(yùn)行的函數(shù)實現(xiàn)的。這不是 大多數(shù)人熟悉的面向?qū)ο缶幊田L(fēng)格 ,但它是一個非常強(qiáng)大的想法。

當(dāng) Russ 加入時,他很快就指出了 I/O 如何完美地融入這個想法,并且?guī)斓陌l(fā)展很快,很大程度上基于三個著名的接口:empty、Writer 和 Reader,平均持有三分之二的數(shù)據(jù)、各一個方法。  這些微小的方法是 Go 的慣用方法,而且無處不在。

接口的工作方式不僅成為 Go 的顯著特征,還成為我們思考庫、通用性和組合的方式。這是令人興奮的事情。但問題就產(chǎn)生在這里。你看,我們走這條路,很大一部分原因是我們經(jīng)??吹椒盒途幊坦膭钜环N這樣一種思維方式:傾向于關(guān)注類型而不是算法、關(guān)注早期的抽象而不是有機(jī)設(shè)計、關(guān)注容器而不是函數(shù)。

我們用語言本身定義了通用容器——映射、切片、數(shù)組、通道——但沒有讓程序員訪問它們所包含的通用性。這可以說是一個錯誤。雖然這些類型可以很好地處理大多數(shù)簡單的編程任務(wù)。但讓人感到困擾的是,語言提供的內(nèi)容和用戶可以控制的內(nèi)容之間存在障礙。

簡而言之,這種思維方式陳年已久,我們花了十多年的時間才糾正過來。Ian Taylor 從一開始就敦促我們面對這個問題,但考慮到接口作為 Go 編程的基石,這很難做到。

批評者經(jīng)常抱怨我們應(yīng)該只做泛型,因為它們 很“簡單”,也許它們可以用在某些語言中,但接口的存在意味著任何新形式的多態(tài)性都必須考慮它們。找到一種與該語言的其余部分良好配合的前進(jìn)方式需要多次嘗試、幾次中止的實現(xiàn)以及數(shù)小時、數(shù)天和數(shù)周的討論。

最終我們請來了一些由 Phil Wadler 領(lǐng)導(dǎo)的類型理論家來幫忙。即使在今天,語言中已經(jīng)有了可靠的通用模型,但接口作為方法集的存在仍然存在一些揮之不去的問題。

如您所知,最終的答案是設(shè)計一個接口的泛化,可以吸收更多形式的多態(tài)性,從“方法集”過渡到“類型集”。這是一個微妙但意義深遠(yuǎn)的舉措,大多數(shù)社區(qū)似乎都同意這一舉措,但我的懷疑態(tài)度并未打消。

有時要花很多年的時間才能搞清楚一件事,甚至搞清楚“自己原來沒太搞清楚”這件事。然后繼續(xù)前進(jìn)。

順便說一句,我希望我們有一個比“泛型”更好的術(shù)語,它起源于一種不同的、以數(shù)據(jù)結(jié)構(gòu)為中心的多態(tài)性風(fēng)格?!皡?shù)多態(tài)性”是 Go 提供的內(nèi)容的正確術(shù)語,但它有些拗口。但我們平時提“泛型”,但也不太準(zhǔn)確。

3.對于開源項目的管理挑戰(zhàn)與教訓(xùn)

要想成功,Go 必須是一個開源項目。但在我們弄清楚關(guān)鍵想法并進(jìn)行有效實施之前,私下開發(fā)會更有成效。因此,前兩年我們需要這個過程不受干擾。

向開源的過渡是一個巨大的變化,而且具有教育意義。社區(qū)的投入是巨大的。與社區(qū)互動需要花費(fèi)大量的時間和精力,尤其是對于 Ian 來說,他竟然還能抽出時間來回答任何人提出的每個問題。但它帶來了更多。我仍然對 Windows 移植的速度如此之快感到驚訝,這完全是由社區(qū)在 Alex Brainman 的指導(dǎo)下完成的。

我們花了很長時間才理解轉(zhuǎn)向開源項目的含義以及如何管理它。我們說服了支持我們的社區(qū),堅持通過強(qiáng)制代碼審查和對細(xì)節(jié)的全面關(guān)注來保持高代碼質(zhì)量,而不是采用快速接受代碼并在提交后進(jìn)行清理的方式。這種做法將更多的工作推回給社區(qū),需要他們了解其價值,否則他們不會感到受到應(yīng)有的歡迎。

圖片圖片

有一個歷史細(xì)節(jié)并不廣為人知。該項目有 4 個不同的內(nèi)容管理系統(tǒng):SVN、Perforce、Mercurial 和 Git。感謝Russ為項目所做的歷史內(nèi)容管理系統(tǒng)的維護(hù)工作。

此外,Go語言項目是獨(dú)立于Goole之外的,盡管Google提供了支持,但核心團(tuán)隊是獨(dú)立的,沒有設(shè)定議程。Google 擁有龐大的內(nèi)部 Go 代碼庫,團(tuán)隊用它來測試和驗證版本,但這是通過從公共存儲庫導(dǎo)入 Google 來完成的。

4.包管理

Go語言的包管理開發(fā)過程做得并不好,關(guān)鍵在于使用純字符串來指定導(dǎo)入語句中的路徑,雖然提供了靈活性,但也帶來了很多問題。

Go核心團(tuán)隊在早期缺乏處理具有大量包版本的包管理器以及解決依賴關(guān)系圖等復(fù)雜問題的經(jīng)驗。盡管如此,我們?nèi)匀辉噲D讓社區(qū)參與解決依賴管理問題,但最終設(shè)計出來時,許多社區(qū)成員感到被輕視。

圖片

這次失敗給團(tuán)隊上了一課,讓我們更加了解如何真正與社區(qū)互動。盡管道路崎嶇不平,但現(xiàn)在事情已經(jīng)得到了解決,出現(xiàn)的設(shè)計在技術(shù)上非常出色,并且對大多數(shù)用戶來說效果很好。

四、寫在最后:Go 做到了

推出 14 年后,我們最后成功了??偟膩碚f,很大程度上是因為最初把設(shè)計和開發(fā) Go 作為一種編寫軟件的方式(而不僅僅是作為一種編程語言)這項決定,才帶領(lǐng)我們來到了這樣一個新地方。

我們到達(dá)這里的部分原因是:

  • 一個強(qiáng)大的標(biāo)準(zhǔn)庫,可實現(xiàn)服務(wù)器代碼所需的大部分基礎(chǔ)知識
  • 并發(fā)性作為該語言的首要組成部分
  • 基于組合而不是繼承的方法
  • 澄清依賴管理的打包模型
  • 集成的快速構(gòu)建和測試工具
  • 嚴(yán)格一致的格式
  • 注重可讀性而非聰明性
  • 兼容性保證

最重要的是,得益于令人難以置信的、樂于助人、且多元化的 Gophers 社區(qū)的支持。

參考鏈接:https://commandcenter.blogspot.com/2024/01/what-we-got-right-what-we-got-wrong.html

責(zé)任編輯:武曉燕 來源: 51CTO技術(shù)棧
相關(guān)推薦

2024-01-08 08:23:07

Go語言代碼

2022-03-28 13:34:26

Go泛型部署泛型

2021-10-23 06:42:14

Go語言接口

2021-10-03 22:18:14

Go語言整數(shù)

2021-10-18 10:53:26

Go 代碼技術(shù)

2020-12-31 09:06:44

Go語言Reflect

2021-10-09 07:52:01

Go程序重命名

2021-10-16 17:53:35

Go函數(shù)編程

2023-11-06 13:32:38

Go編程

2017-12-27 14:52:21

JSGo編程語言

2018-03-12 22:13:46

GO語言編程軟件

2023-05-24 09:31:51

CGo

2017-11-27 11:08:33

編程C語言代碼

2019-02-11 08:32:22

編程語言Go

2023-02-10 09:40:36

Go語言并發(fā)

2021-01-13 10:52:29

C語言Linux計算機(jī)領(lǐng)域

2023-01-12 08:52:50

GoroutinesGo語言

2016-10-13 19:11:45

Go語言Java語言

2012-11-20 10:20:57

Go

2024-03-01 20:16:03

GoRust語言
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號