你沒聽說過的 Go 語言驚人優(yōu)點(diǎn)
編譯自: https://medium.freecodecamp.org/here-are-some-amazing-advantages-of-go-that-you-dont-hear-much-about-1af99de3b23a
作者: Kirill Rogovoy
譯者: imquanquan
在這篇文章中,我將討論為什么你需要嘗試一下 Go 語言,以及應(yīng)該從哪里學(xué)起。
Go 語言是可能是最近幾年里你經(jīng)常聽人說起的編程語言。盡管它在 2009 年已經(jīng)發(fā)布了,但它最近才開始流行起來。

根據(jù) Google 趨勢(shì),Go 語言非常流行。
這篇文章不會(huì)討論一些你經(jīng)常看到的 Go 語言的主要特性。
相反,我想向您介紹一些相當(dāng)小眾但仍然很重要的功能。只有在您決定嘗試 Go 語言后,您才會(huì)知道這些功能。
這些都是表面上沒有體現(xiàn)出來的驚人特性,但它們可以為您節(jié)省數(shù)周或數(shù)月的工作量。而且這些特性還可以使軟件開發(fā)更加愉快。
閱讀本文不需要任何語言經(jīng)驗(yàn),所以不必?fù)?dān)心你還不了解 Go 語言。如果你想了解更多,可以看看我在底部列出的一些額外的鏈接。
我們將討論以下主題:
- GoDoc
- 靜態(tài)代碼分析
- 內(nèi)置的測(cè)試和分析框架
- 競(jìng)爭(zhēng)條件檢測(cè)
- 學(xué)習(xí)曲線
- 反射
- Opinionatedness
- 文化
請(qǐng)注意,這個(gè)列表不遵循任何特定順序來討論。
GoDoc
Go 語言非常重視代碼中的文檔,所以也很簡(jiǎn)潔。
GoDoc 是一個(gè)靜態(tài)代碼分析工具,可以直接從代碼中創(chuàng)建漂亮的文檔頁(yè)面。GoDoc 的一個(gè)顯著特點(diǎn)是它不使用任何其他的語言,如 JavaDoc、PHPDoc 或 JSDoc 來注釋代碼中的結(jié)構(gòu),只需要用英語。
它使用從代碼中獲取的盡可能多的信息來概述、構(gòu)造和格式化文檔。它有多而全的功能,比如:交叉引用、代碼示例,并直接鏈接到你的版本控制系統(tǒng)倉(cāng)庫(kù)。
而你需要做的只有添加一些像 // MyFunc transforms Foo into Bar 這樣子的老牌注釋,而這些注釋也會(huì)反映在的文檔中。你甚至可以添加一些通過網(wǎng)絡(luò)界面或者在本地可以實(shí)際運(yùn)行的 代碼示例 。
GoDoc 是 Go 的唯一文檔引擎,整個(gè)社區(qū)都在使用。這意味著用 Go 編寫的每個(gè)庫(kù)或應(yīng)用程序都具有相同的文檔格式。從長(zhǎng)遠(yuǎn)來看,它可以幫你在瀏覽這些文檔時(shí)節(jié)省大量時(shí)間。
例如,這是我最近一個(gè)小項(xiàng)目的 GoDoc 頁(yè)面: pullkee — GoDoc 。
靜態(tài)代碼分析
Go 嚴(yán)重依賴于靜態(tài)代碼分析。例如用于文檔的 godoc ,用于代碼格式化的 gofmt ,用于代碼風(fēng)格的 golint ,等等。
它們是如此之多,甚至有一個(gè)總攬了它們的項(xiàng)目 gometalinter ,將它們組合成了單一的實(shí)用程序。
這些工具通常作為獨(dú)立的命令行應(yīng)用程序?qū)崿F(xiàn),并可輕松與任何編碼環(huán)境集成。
靜態(tài)代碼分析實(shí)際上并不是現(xiàn)代編程的新概念,但是 Go 將其帶入了絕對(duì)的范疇。我無法估量它為我節(jié)省了多少時(shí)間。此外,它給你一種安全感,就像有人在你背后支持你一樣。
創(chuàng)建自己的分析器非常簡(jiǎn)單,因?yàn)?Go 有專門的內(nèi)置包來解析和加工 Go 源碼。
你可以從這個(gè)鏈接中了解到更多相關(guān)內(nèi)容: GothamGo Kickoff Meetup: Alan Donovan 的 Go 靜態(tài)分析工具 。
內(nèi)置的測(cè)試和分析框架
您是否曾嘗試為一個(gè)從頭開始的 JavaScript 項(xiàng)目選擇測(cè)試框架?如果是這樣,你或許會(huì)理解經(jīng)歷這種 過度分析(analysis paralysis)的痛苦。您可能也意識(shí)到您沒有使用其中 80% 的框架。
一旦您需要進(jìn)行一些可靠的分析,問題就會(huì)重復(fù)出現(xiàn)。
Go 附帶內(nèi)置測(cè)試工具,旨在簡(jiǎn)化和提高效率。它為您提供了最簡(jiǎn)單的 API,并做出最小的假設(shè)。您可以將它用于不同類型的測(cè)試、分析,甚至可以提供可執(zhí)行代碼示例。
它可以開箱即用地生成便于持續(xù)集成的輸出,而且它的用法很簡(jiǎn)單,只需運(yùn)行 go test。當(dāng)然,它還支持高級(jí)功能,如并行運(yùn)行測(cè)試,跳過標(biāo)記代碼,以及其他更多功能。
競(jìng)爭(zhēng)條件檢測(cè)
您可能已經(jīng)聽說了 Goroutine,它們?cè)?Go 中用于實(shí)現(xiàn)并發(fā)代碼執(zhí)行。如果你未曾了解過, 這里 有一個(gè)非常簡(jiǎn)短的解釋。
無論具體技術(shù)如何,復(fù)雜應(yīng)用中的并發(fā)編程都不容易,部分原因在于競(jìng)爭(zhēng)條件的可能性。
簡(jiǎn)單地說,當(dāng)幾個(gè)并發(fā)操作以不可預(yù)測(cè)的順序完成時(shí),競(jìng)爭(zhēng)條件就會(huì)發(fā)生。它可能會(huì)導(dǎo)致大量的錯(cuò)誤,特別難以追查。如果你曾經(jīng)花了一天時(shí)間調(diào)試集成測(cè)試,該測(cè)試僅在大約 80% 的執(zhí)行中起作用?這可能是競(jìng)爭(zhēng)條件引起的。
總而言之,在 Go 中非常重視并發(fā)編程,幸運(yùn)的是,我們有一個(gè)強(qiáng)大的工具來捕捉這些競(jìng)爭(zhēng)條件。它完全集成到 Go 的工具鏈中。
您可以在這里閱讀更多相關(guān)信息并了解如何使用它: 介紹 Go 中的競(jìng)爭(zhēng)條件檢測(cè) - Go Blog 。
學(xué)習(xí)曲線
您可以在一個(gè)晚上學(xué)習(xí)所有的 Go 語言功能。我是認(rèn)真的。當(dāng)然,還有標(biāo)準(zhǔn)庫(kù),以及不同的,更具體領(lǐng)域的***實(shí)踐。但是兩個(gè)小時(shí)就足以讓你自信地編寫一個(gè)簡(jiǎn)單的 HTTP 服務(wù)器或命令行應(yīng)用程序。
Go 語言擁有 出色的文檔 ,大部分高級(jí)主題已經(jīng)在他們的博客上進(jìn)行了介紹: Go 編程語言博客 。
比起 Java(以及 Java 家族的語言)、Javascript、Ruby、Python 甚至 PHP,你可以更輕松地把 Go 語言帶到你的團(tuán)隊(duì)中。由于環(huán)境易于設(shè)置,您的團(tuán)隊(duì)在完成***個(gè)生產(chǎn)代碼之前需要進(jìn)行的投資要小得多。
反射
代碼反射本質(zhì)上是一種隱藏在編譯器下并訪問有關(guān)語言結(jié)構(gòu)的各種元信息的能力,例如變量或函數(shù)。
鑒于 Go 是一種靜態(tài)類型語言,當(dāng)涉及更松散類型的抽象編程時(shí),它會(huì)受到許多各種限制。特別是與 Javascript 或 Python 等語言相比。
此外,Go 沒有實(shí)現(xiàn)一個(gè)名為泛型的概念 ,這使得以抽象方式處理多種類型更具挑戰(zhàn)性。然而,由于泛型帶來的復(fù)雜程度,許多人認(rèn)為不實(shí)現(xiàn)泛型對(duì)語言實(shí)際上是有益的。我完全同意。
根據(jù) Go 的理念(這是一個(gè)單獨(dú)的主題),您應(yīng)該努力不要過度設(shè)計(jì)您的解決方案。這也適用于動(dòng)態(tài)類型編程。盡可能堅(jiān)持使用靜態(tài)類型,并在確切知道要處理的類型時(shí)使用 接口(interface)。接口在 Go 中非常強(qiáng)大且無處不在。
但是,仍然存在一些情況,你無法知道你處理的數(shù)據(jù)類型。一個(gè)很好的例子是 JSON。您可以在應(yīng)用程序中來回轉(zhuǎn)換所有類型的數(shù)據(jù)。字符串、緩沖區(qū)、各種數(shù)字、嵌套結(jié)構(gòu)等。
為了解決這個(gè)問題,您需要一個(gè)工具來檢查運(yùn)行時(shí)的數(shù)據(jù)并根據(jù)其類型和結(jié)構(gòu)采取不同行為。 反射(Reflect)可以幫到你。Go 擁有***的反射包,使您的代碼能夠像 Javascript 這樣的語言一樣動(dòng)態(tài)。
一個(gè)重要的警告是知道你使用它所帶來的代價(jià) —— 并且只有知道在沒有更簡(jiǎn)單的方法時(shí)才使用它。
你可以在這里閱讀更多相關(guān)信息: 反射的法則 — Go 博客 .
您還可以在此處閱讀 JSON 包源碼中的一些實(shí)際代碼: src/encoding/json/encode.go — Source Code
Opinionatedness(專制獨(dú)裁的 Go)
順便問一下,有這樣一個(gè)單詞嗎?
來自 Javascript 世界,我面臨的最艱巨的困難之一是決定我需要使用哪些約定和工具。我應(yīng)該如何設(shè)計(jì)代碼?我應(yīng)該使用什么測(cè)試庫(kù)?我該怎么設(shè)計(jì)結(jié)構(gòu)?我應(yīng)該依賴哪些編程范例和方法?
這有時(shí)候基本上讓我卡住了。我需要花時(shí)間思考這些事情而不是編寫代碼并滿足用戶。
首先,我應(yīng)該注意到我完全知道這些慣例的來源,它總是來源于你或者你的團(tuán)隊(duì)。無論如何,即使是一群經(jīng)驗(yàn)豐富的 Javascript 開發(fā)人員也很容易發(fā)現(xiàn)他們?cè)趯?shí)現(xiàn)相同的結(jié)果時(shí),而大部分的經(jīng)驗(yàn)卻是在完全不同的工具和范例上。
這導(dǎo)致整個(gè)團(tuán)隊(duì)中出現(xiàn)過度分析,并且使得個(gè)體之間更難以相互協(xié)作。
嗯,Go 是不同的。即使您對(duì)如何構(gòu)建和維護(hù)代碼有很多強(qiáng)烈的意見,例如:如何命名,要遵循哪些結(jié)構(gòu)模式,如何更好地實(shí)現(xiàn)并發(fā)。但你只有一個(gè)每個(gè)人都遵循的風(fēng)格指南。你只有一個(gè)內(nèi)置在基本工具鏈中的測(cè)試框架。
雖然這似乎過于嚴(yán)格,但它為您和您的團(tuán)隊(duì)節(jié)省了大量時(shí)間。當(dāng)你寫代碼時(shí),受一點(diǎn)限制實(shí)際上是一件好事。在構(gòu)建新代碼時(shí),它為您提供了一種更直接的方法,并且可以更容易地調(diào)試現(xiàn)有代碼。
因此,大多數(shù) Go 項(xiàng)目在代碼方面看起來非常相似。
文化
人們說,每當(dāng)你學(xué)習(xí)一門新的口語時(shí),你也會(huì)沉浸在說這種語言的人的某些文化中。因此,您學(xué)習(xí)的語言越多,您可能會(huì)有更多的變化。
編程語言也是如此。無論您將來如何應(yīng)用新的編程語言,它總能給你帶來新的編程視角或某些特別的技術(shù)。
無論是函數(shù)式編程, 模式匹配(pattern matching)還是 原型繼承(prototypal inheritance)。一旦你學(xué)會(huì)了它們,你就可以隨身攜帶這些編程思想,這擴(kuò)展了你作為軟件開發(fā)人員所擁有的問題解決工具集。它們也改變了你閱讀高質(zhì)量代碼的方式。
而 Go 在這方面有一項(xiàng)了不起的財(cái)富。Go 文化的主要支柱是保持簡(jiǎn)單,腳踏實(shí)地的代碼,而不會(huì)產(chǎn)生許多冗余的抽象概念,并將可維護(hù)性放在首位。大部分時(shí)間花費(fèi)在代碼的編寫工作上,而不是在修補(bǔ)工具和環(huán)境或者選擇不同的實(shí)現(xiàn)方式上,這也是 Go 文化的一部分。
Go 文化也可以總結(jié)為:“應(yīng)當(dāng)只用一種方法去做一件事”。
一點(diǎn)注意事項(xiàng)。當(dāng)你需要構(gòu)建相對(duì)復(fù)雜的抽象代碼時(shí),Go 通常會(huì)妨礙你。好吧,我會(huì)說這是簡(jiǎn)單的權(quán)衡。
如果你真的需要編寫大量具有復(fù)雜關(guān)系的抽象代碼,那么***使用 Java 或 Python 等語言。然而,這種情況卻很少。
在工作時(shí)始終使用***的工具!
總結(jié)
你或許之前聽說過 Go,或者它暫時(shí)在你圈子以外的地方。但無論怎樣,在開始新項(xiàng)目或改進(jìn)現(xiàn)有項(xiàng)目時(shí),Go 可能是您或您團(tuán)隊(duì)的一個(gè)非常不錯(cuò)的選擇。
這不是 Go 的所有驚人的優(yōu)點(diǎn)的完整列表,只是一些被人低估的特性。
請(qǐng)嘗試一下從 Go 之旅 來開始學(xué)習(xí) Go,這將是一個(gè)令人驚嘆的開始。
如果您想了解有關(guān) Go 的優(yōu)點(diǎn)的更多信息,可以查看以下鏈接:
- 你為什么要學(xué)習(xí) Go? - Keval Patel
- 告別Node.js - TJ Holowaychuk
并在評(píng)論中分享您的閱讀感悟!
即使您不是為了專門尋找新的編程語言語言,也值得花一兩個(gè)小時(shí)來感受它。也許它對(duì)你來說可能會(huì)變得非常有用。
不斷為您的工作尋找***的工具!
題圖來自 https://github.com/ashleymcnamara/gophers 的圖稿