這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。按照慣例,第一篇博文總要說點曆史,對吧?我作為軟體開發人員,主要還是使用 PHP 語言。第一次接觸它還是我在高中的時候,跟一個朋友一起開發一個項目。我們想為項目建一個網站,正好發現一個用 PHP 語言,代碼寫得非常整齊,並且預打包的解決方案。那個時候,我完全不懂這些代碼是幹嘛的,也沒有花時間去弄懂它。多年之後,我再次與 PHP 相遇。在我進入大學的前 6 個月(我想大約 7 年前),PHP 成了我主要關注的語言之一。兩年前,我第一次經人介紹瞭解到 Go 語言。我大部分專業經曆都來自於位於利茲中心的代理機構。這是一個夢幻般的公司,我從中學到了很多,因為很早我就被給予了很高的自由度。我為一個範圍很廣的項目工作:標準的 CMS 構建,定製 API 介面,手機應用程式,為了提高效率的自動化,部署和基礎架構設計,以及其他很多功能。在代理機構的這段時間裡,我和一個我們聘請的實習產生為了朋友。他真的是個天才,也是他突然向我介紹 Go 語言。我說我會試試,然後說一下我對它的看法。很快,我就覺得我喜歡上它了。跟 PHP 相比,更好的效能,型別安全,支援並發,本地編譯後的二進位檔案,相當小,啟動速度相當快,這非常地誘人!如果你從 PHP 轉 Go 開發,那麼會有一大堆讓你感到激動的東西。奇怪的是,我其實並沒有那麼喜歡它。我認為它的文法很怪,它的工具還好,但處理錯誤是如此地繁瑣,(甚至,)天哪,地球上怎麼還有像 Go 語言這樣沒有支援泛型的語言?我記得與這位實習生進行了很多類似的對話,他可能告訴我所有我後來自己也慢慢意識到的事情,但是我繼續尋找新的東西來學習 PHP 以外的東西,現在改為 Go 語言也是這樣。## 使用 Scala 的一年(The Year of Scala)我的搜尋很快把我帶到了 Scala 的世界。如果你沒怎麼聽過 Scala 的話,它是運行在 JVM 上的函數程式設計語言。當時很有吸引力的一點是 JVM 很快(一旦啟動並運行起來之後),函數式編程當時瘋狂地席捲了編程界。我迷上了 Scala,花了一年時間圍繞著它,學習它的文法。當我愛上它時,儘管編譯時間比 Go 長,但使用 SBT 的工具實際上也沒有那麼糟糕(得益於增量編譯)。我學習其文法,花了一些時間之後,就能像編寫 Java 一樣編寫 Scala,而且使用的文法還更少一些。接下來,我專註於學習函數編程原理,如更純粹,引用透明性,不修改狀態(等函數式編程的原則)。在編寫 PHP 時,我曾遵循過許多這裡描述的原則,但並沒有想過要如何編寫一個純函數式的應用程式。在我使用 Scala 的過程中,我大量閱讀了相關部落格,閱讀了一些 Scala 社區裡比較流行的書,參加 Martin Odersky 使用 Scala 函數式編程的課程。我覺得我不能只是待在我能做出有用的東西的地方。我應該待在可以提高在 Scala 項目工作的機會的地方,我對自己的 Scala 技能應該有足夠的信心,我應該能為這樣的項目工作。然而情況卻是...我並不這麼覺得。我還是覺得其他人的代碼很讓人迷惑,很難閱讀。覺得其他人寫的每一個庫都有自己不同的(編程)風格,並且還需要學習大量的詞彙。我瞭解一些廣泛被使用的庫,像 [cats](https://typelevel.org/cats/) 和 [shapeless](https://github.com/milessabin/shapeless),但還是不明白它們幹了什麼或者為什麼你需要它們。回過頭來,不要誤解我的意思。Scala 是一門令人印象深刻的語言,我非常尊重那些使用這門語言工作的人。它本身沒有任何限制,這是好事也是壞事(對於我來說,是壞事)。我喜歡類似於保持不變的想法,難以置信的是編譯器撿起了類型錯誤。這非常罕見,它丟掉了重要的東西,並讓錯誤可以在運行時發生。我確實用 Scala 做了一些事情,但也弄得我越來越沮喪。我曾想解決我想解決的問題,但總是因為各種原因弄得焦頭爛額。要麼就是我缺乏函數編程的經驗技巧,要麼就是像 JVM 啟動時間這樣的事情讓我感到沮喪。不知道為什麼,我在這一年後仍然發現還有 Scala 的新文法(需要我去學)。我覺得我已經在這條路上走了一年,但收穫甚少。## 重回 Go 語言(Back to Go Again)在使用 Scala 一年以後,我決定再給 Go 一個機會。(因為)我發現沒有其他的語言能像 Go 一樣在方框中打這麼多勾,使用 Scala 的一年只是讓我增加更多的方框來打勾。這些方框都有什麼呢?- 快速編譯:雖然 SBT 增量式編譯在開發時可以加快編譯速度,從頭開始編譯還是需要花費很長的時間,而且即使是 SBT 增量式編譯,花的時間也比 `go build` 花的時間長。- 快速啟動應用:我對於開發 CLI 工具非常感興趣。早期使用 Go 和 Scala 語言開發的庫中都有一個為了建立 CLI 應用的庫。這對於用來測試不同語言開發的應用的啟動速度非常有用。- 低記憶體佔用:我並不是研究 JVM 直接使用多少記憶體的狂熱粉絲。但我也知道如果我想將我做的事情 Docker 化,對於今天的 JVM 來說還是個問題。- 功能豐富,風格一致,但簡單的標準庫:Scala 擁有大量的庫,但你可以發現(其實)大量依賴於 Java 庫。有一些並不是那麼令人愉快。最重要的是,當你開始引入這些依賴關係時,心裡就會開始覺得(為啥)你不得不下載整個互連網來做一些非常基本的事情。- 編譯時間類型檢查:Scala 在這方面表現出色,但多數情況下,你需要犧牲可讀性作為代價。在某些情況下,Go 會漏掉一些編譯時間的類型檢查,但這種情況非常罕見,因為通常有其他可以在編譯時間做類型檢查的解決方案。- 垃圾收集和型別安全:我不想接觸太低層的東西,但我還是想比我使用 PHP 時能對應用程式幹什麼有更多的控制。- 內嵌的並發原語:來自於 PHP,這是我想更多解釋的地方。使用 Scala 開發程式時,我有機會用上並發,但從來沒有像使用 Go 一樣對應用程式能控製得這麼多。- 廣泛採用的編程風格約定:來自於 PHP,PHP 標準建議(PSR)相當流行,我知道我喜歡擁有能夠到處使用的代碼風格約定的語言。我相信很多語言都能從中受益,包括 Scala。對於我來說,Go 符合所有這些要求,甚至更多。我認為 Go 給了你很多可以開箱即用的東西。你也可以在其他地方找到這些東西,但並不像 Go 一樣全,而且整潔。開始激怒我的一些 Go 的特性也變得可以接受了。我覺得我最終明白了一些東西,像 Go 語言一樣,也需要作出一些妥協;以確保像上面的那些框可以被打勾。為了你可以得到更多的好處,另外一些地方就得難受一點,但有一點非常清晰,語言總體上被設計成最大化開發生產效率。錯誤控制就是個很好的例子。它很繁瑣,有時它有一點不是那麼有用。然而,它讓函數裡面哪裡會發生錯誤變得非常清晰,這意味著,當你閱讀別人代碼的時候,你能夠清楚地知道什麼時候,或者為什麼錯誤會發生。另外一個可以做出這個判斷的,開始時令我感到困惑的是 `context` 包。我本來並不是很喜歡它,並且認為它處理問題用了一種非常冗長的方式。為什麼我們不能直接殺掉 goroutines 呢?`context` 跟錯誤非常像,它的冗長也是顯式的,告訴你某個給定代碼的某些內容很可能在某些時候被取消。你不能殺掉 goroutine,因為你沒辦法處理它產生的 goroutine?畢竟他們不再是孩子。約定,工具使得 Go 語言開發的項目令人難以置信地一致。到當前為止,比我用過的任何語言都要好。當你有像 `goimports` 和 `gometalinter` 一樣的工具,就不奇怪每一個項目都有相同的代碼風格,甚至相同的文檔風格。工具也能協助你避免代碼中相同的 bug 和減少誤解。我開始用 Go 寫軟體後,覺得最棒的是,我可以真正解決問題了。我想解決的實際問題,不僅僅是一些隨機的數學教學問題。最近一段時間(我希望可以寫得很快),我在製作一些工具來協助自動化我的 Arch Linux 案頭的一些地方。我寫了一些工具去管理我的工作區,為一些東西顯示通知,做一些像自動設定我的顯示器(都是一些解決案頭環境的問題,但它是一切工作的開始)。學習 Scala 時,對於一些數學問題,我建議建立的解決方案非常有意思,但卻(糾結於)沒能寫出解決實際問題的軟體,直到使用 Go 語言才釋然。這不是 Scala 的錯誤,它確實能夠解決問題。我知道這是一個巨大的範式轉變,鑒於我的曆史,我將需要一個很大半徑的彎曲學習曲線。對於我來說 Go 沒有學習門檻;實際上 Go 本來壓根就沒有學習門檻。沒有很複雜的編譯工具,文法可以一下子裝進你的腦裡,你能很快上手。可能你從第一天開始就可以閱讀別人的代碼,包括閱讀標準庫中的代碼。Go 語言不是完美的,但它在不斷完善中。我對這門語言的未來感到非常興奮,並且從中看到了我想要的東西。
via: https://www.elliotdwright.com/2018/02/26/there-and-back-again/
作者:Elliot Wright 譯者:gogeof 校對:polaris1119
本文由 GCTT 原創編譯,Go語言中文網 榮譽推出
本文由 GCTT 原創翻譯,Go語言中文網 首發。也想加入譯者行列,為開源做一些自己的貢獻嗎?歡迎加入 GCTT!
翻譯工作和譯文發表僅用於學習和交流目的,翻譯工作遵照 CC-BY-NC-SA 協議規定,如果我們的工作有侵犯到您的權益,請及時聯絡我們。
歡迎遵照 CC-BY-NC-SA 協議規定 轉載,敬請在本文中標註並保留原文/譯文連結和作者/譯者等資訊。
文章僅代表作者的知識和看法,如有不同觀點,請樓下排隊吐槽
714 次點擊