1. 吵翻了!到底該選 Rust 還是 Go,成2023年最大技術(shù)分歧

        共 11159字,需瀏覽 23分鐘

         ·

        2023-08-24 08:31

        編譯 | 核子可樂、Tina

        2023 年,我們有一千個學(xué)習(xí) Rust 的理由。

        8 月 7 日,Rust 基金會發(fā)布了 2022 年度 Rust 調(diào)查報(bào)告結(jié)果,報(bào)告顯示 Rust 采用率不斷提高,超過 90% 的調(diào)查受訪者表示自己是 Rust 用戶;29.7% 的受訪者表示,他們在工作中的大部分編碼工作都使用 Rust,比上一年顯著增加了 51.8%。

        毋庸置疑,Rust 以其卓越的內(nèi)存安全性和并發(fā)性能正日益成為開發(fā)者關(guān)注的焦點(diǎn)。然而,同樣令人難以忽視的是 Go,這門曾被評選為年度編程語言的相對比較“老牌”的選手。

        Go 語言誕生于 2009 年,一開始就因其獨(dú)特的并發(fā)模型和強(qiáng)大的性能優(yōu)勢而受到了極大關(guān)注。值得注意的是,跟 Rust 語言一樣,Go 語言的創(chuàng)建者也同樣“討厭”C++,并且 Go 同樣也都是云原生的主導(dǎo)語言

        而在 Stack Overflow 2022 開發(fā)者調(diào)查中,對于“讓人愛恨交織的編程語言”這個問題,在 7 萬份回復(fù)中,程序員們明顯也更為偏愛 Rust,86% 的人表示喜歡 Rust,而 64% 的人表示喜歡 Go。面對 Rust 的火爆現(xiàn)狀,一些開發(fā)者發(fā)出了靈魂提問:2023 年,Go 還值得學(xué)習(xí)嗎?

        71901c7919047423908f68d660704e80.webp

        bd21e1218d9cbb2e3334769a337a070a.webp

        另外,這兩天,到底是該選 Rust 還是選 Go,也成為了 Hacker News 上的一個熱門話題:

        721c50edff009c9c573a4ea5dc100e63.webp

        一位挺 Rust 的網(wǎng)友說道:“我也為這個選擇煩惱了很久。最終 Rust 勝出了。首先,我感覺 Rust 更接近于以前 Pascal 時(shí)代的東西,你可以控制一切;其次,如果 wasm 和相關(guān)技術(shù)大爆發(fā),Rust 將是一個更安全的選擇;然后,我們已經(jīng)有了 Python 用于快速開發(fā),因此選擇一些更極端的東西是有道理的,Go 在某種程度上處于中間地帶。最后,Rust 應(yīng)用于內(nèi)核且備受關(guān)注,所以不太可能會被淘汰。”

        另一位持反對意見的開發(fā)者則表示,“我從事 Go 開發(fā)已經(jīng)快十年了,但最近我也嘗試了下 Rust。我認(rèn)為目前有一些對 Rust 的強(qiáng)制性和誤導(dǎo)性偏好,從我在各種初創(chuàng)公司的經(jīng)驗(yàn),包括我目前所在的公司來看,對于后端開發(fā)來說,Go 是迄今為止最佳選擇!注意,在性能、功能或其他方面……這兩種語言非常非常相似!”

        不得不說的是,Go 和 Rust 絕對都是優(yōu)秀的編程語言。它們現(xiàn)代、強(qiáng)大、應(yīng)用廣泛,而且有著卓越的性能表現(xiàn)。但如果直接對比 Go 和 Rust 誰更好之類的,真的沒啥意義,因?yàn)槊糠N編程語言都代表著背后一系列深層次的權(quán)衡。不同的語言會針對不同的需求進(jìn)行優(yōu)化,因此我們在選擇語言時(shí),也應(yīng)該考慮自己想要用它解決什么樣的問題。所以我們將從 Go 和 Rust 語言的適用場景出發(fā),探討下 Go 與 Rust 的設(shè)計(jì)之“道”。

        雖然 Rust 和 Go 在語法和風(fēng)格上差別很大,但它們都是構(gòu)建軟件的一流工具。下面咱們開始具體分析。

        Go 與 Rust:相似性

        Rust 和 Go 有很多共同點(diǎn),所以人們才經(jīng)常把二者拿來相提并論。那它們有哪些共同目標(biāo)?


        Rust 是一種低級靜態(tài)類型的多范式編程語言,更多關(guān)注安全性和性能。


        —Gints Dreimanis

        而:


        Go 是一種開源編程語言,能夠輕松構(gòu)建起簡單、可靠且高效的軟件。


        —golang.org

        內(nèi)存安全

        Go 和 Rust 都屬于重視內(nèi)存安全的現(xiàn)代編程語言。在 C 和 C++ 等舊語言發(fā)展的這幾十年間,我們已經(jīng)清楚地意識到,引發(fā)錯誤和 bug 的核心原因之一,就是對內(nèi)存的不安全 / 不正確訪問。

        于是 Rust 和 Go 各自給出了不同的解決思路,但二者的目標(biāo)都是在內(nèi)存管理方面更智能、更安全,幫助開發(fā)者編寫出正確且性能極佳的程序。

        快速、緊湊的可執(zhí)行文件

        二者都屬于編譯語言,也就是說可以將程序直接翻譯成可執(zhí)行的機(jī)器代碼,這樣就能把程序部署成單一二進(jìn)制文件。跟 Python 和 Ruby 等解釋性語言不同,我們不需要隨程序一同發(fā)布解釋器和大量的庫 / 依賴項(xiàng)。作為這個核心優(yōu)勢的直接體現(xiàn),Rust 和 Go 程序的運(yùn)行速度往往比解釋性語言更快。

        通用型語言

        Rust 和 Go 都屬于功能強(qiáng)大且可擴(kuò)展的通用編程語言,大家可以用它們開發(fā)出各種現(xiàn)代軟件——從 Web 應(yīng)用程序到分布式微服務(wù),還包括嵌入式微控制器和移動應(yīng)用等等。

        兩者都擁有優(yōu)秀的標(biāo)準(zhǔn)庫和蓬勃發(fā)展的第三方生態(tài)系統(tǒng),外加強(qiáng)大的商業(yè)支持與龐大的用戶基礎(chǔ)。二者已經(jīng)存在多年,并將在未來幾年繼續(xù)保持旺盛的發(fā)展勢頭。如今,學(xué)習(xí) Go 或者 Rust 將是非常合理的時(shí)間和精力投入方向。

        務(wù)實(shí)的編程風(fēng)格

        兩者既不過多偏向函數(shù)式語言(例如 Scala 或 Elixir),也不完全面向?qū)ο螅ɡ?Java 和 C#)。相反,雖然 Go 和 Rust 都具備函數(shù)式及面向?qū)ο缶幊痰墓δ?,但卻始終強(qiáng)調(diào)務(wù)實(shí)取向——即以最合適的方式解決問題,而不是通過“意識形態(tài)”強(qiáng)迫大家用特定的方法做事。

        但如果您確實(shí)喜歡函數(shù)式編程風(fēng)格,那 Rust 這邊的相關(guān)工具選項(xiàng)更多,這也是 Rust 優(yōu)于 Go 的一點(diǎn)。

        我們當(dāng)然可以爭論什么才是真正“面向?qū)ο蟆钡恼Z言。但公平地講,C++、Java 或者 C# 用戶所期望的那種面向?qū)ο缶幊田L(fēng)格,在 Go 或者 Rust 中確實(shí)不存在。
        —Jack Mott
        大規(guī)模開發(fā)

        Rust 和 Go 都為大規(guī)模編程提供不少有用功能,所以它們都能適應(yīng)大開發(fā)團(tuán)隊(duì)作戰(zhàn)和大體量代碼庫的現(xiàn)實(shí)需求。

        例如,C 程序員多年來一直在爭論應(yīng)該把括號放在哪里,還有代碼要不要用制表符或空格進(jìn)行縮進(jìn);但 Rust 和 Go 早已使用標(biāo)準(zhǔn)格式化工具(Go 有 gofmt,Rust 則是 rustfmt)徹底解決了這些問題。它們會使用符合規(guī)范的風(fēng)格自動重寫你的代碼。

        并不是說這種特定的格式有多精妙,而是 Rust 和 Go 程序員更加務(wù)實(shí)、寧愿選擇統(tǒng)一的執(zhí)行標(biāo)準(zhǔn)。

        gofmt 的風(fēng)格也許不是每個人的最愛,但 gofmt 卻能幫到每一個人。
        —Rob Pike

        這兩種語言的另一大優(yōu)勢,體現(xiàn)在構(gòu)建管線上。二者都有優(yōu)秀、內(nèi)置且性能出色的標(biāo)準(zhǔn)構(gòu)建與依賴項(xiàng)管理工具。就是說程序員不必跟復(fù)雜的第三方構(gòu)建系統(tǒng)對抗,也用不著每隔幾年就學(xué)習(xí)一種新系統(tǒng)。

        我在職業(yè)生涯早期用的是 Java 和 Ruby,所以編寫 Go 和 Rust 代碼一直讓我有點(diǎn)畏懼、覺得自己掌握不了。但等到進(jìn)入谷歌并看到用 Go 編寫的服務(wù)時(shí),我才真正松了口氣,因?yàn)槲野l(fā)現(xiàn)它很容易構(gòu)建和運(yùn)行。
        Rust 也是如此。雖然我只在小規(guī)模項(xiàng)目上進(jìn)行過研究,但也看得出它的易用性。我希望那些能夠無限配置的構(gòu)建系統(tǒng)早點(diǎn)成為歷史,現(xiàn)在的新語言都附帶自己的專用構(gòu)建工具而且能夠開箱即用,這樣不好嗎?
        —Sam Rose
        到底選 Rust 還是 Go?

        聊了這么多問題,再加上兩種語言都設(shè)計(jì)得如此精良、功能如此強(qiáng)大,那這場比拼到底有沒有結(jié)果?或者說,既然二者都是非常出色的選項(xiàng),那為什么人們還會在社交媒體上出離憤怒,撰寫長篇累牘的評論博文放出“白癡才用 Rust”或者“Go 根本不能算編程語言”之類的狠話?

        有些人當(dāng)然只是為了宣泄情緒,但這顯然無助于解決實(shí)際問題。至少在項(xiàng)目中該用哪種語言、或者該靠哪種語言闖蕩編程世界這種事上,嗓門大顯然無助于做出正確選擇。

        下面咱們回到成年人的討論,看看理性分析之下 Rust 和 Go 之間如何互有長短。

        Go 對 Rust:性能

        之前已經(jīng)提到,Go 和 Rust 生成的程序運(yùn)行速度都很快,因?yàn)樗鼈儠痪幾g成本機(jī)機(jī)器碼,無需通過解釋器或虛擬機(jī)這個步驟。

        但 Rust 的性能還是要更勝一籌,甚至能夠與被稱為業(yè)界性能標(biāo)桿的 C 和 C++ 相媲美。而且跟這些老牌語言不同的是,Rust 還提供內(nèi)存安全與并發(fā)安全機(jī)制,同時(shí)幾乎不影響執(zhí)行速度。Rust 還允許開發(fā)者構(gòu)建復(fù)雜抽象,又無需在運(yùn)行時(shí)承受性能損失。

        相比之下,雖然 Go 程序的性能也不錯,但其設(shè)計(jì)重心主要在于開發(fā)速度(包括編譯)、而非執(zhí)行程度。Go 程序員更傾向于代碼的清晰可讀,所以運(yùn)行速度要稍遜幾分。

        Go 編譯器也不會花費(fèi)太多時(shí)間來生成最高效的機(jī)器碼,它更關(guān)心如何快速編譯大量代碼。所以在運(yùn)行時(shí)基準(zhǔn)測試中,往往是 Rust 程序要壓 Go 程序一頭。

        Rust 的運(yùn)行時(shí)性能還具有良好的一致性和可預(yù)測性,因?yàn)樗鼪]有使用垃圾收集。Go 的垃圾收集器非常高效,而且做了優(yōu)化以盡可能縮短暫停時(shí)長(隨著 Go 新版本的發(fā)布,暫停時(shí)長也是越來越短)。但無論如何,垃圾收集總會給程序的行為方式帶來一些不可預(yù)測性,而這對某些特定應(yīng)用(比如嵌入式系統(tǒng))而言可能很嚴(yán)重、甚至完全不可接受。

        因?yàn)?Rust 的目標(biāo)是讓程序員完全控制底層硬件,所以 Rust 程序都能深度優(yōu)化以接近機(jī)器的最大理論性能。如此一來,Rust 就在執(zhí)行速度勝過其他一切的特定應(yīng)用場景下成為最佳選項(xiàng),此類用例包括游戲編程、操作系統(tǒng)內(nèi)核、網(wǎng)絡(luò)瀏覽器組件和實(shí)時(shí)控制系統(tǒng)等。

        簡單性

        如果一種編程語言過于難學(xué)、把大多數(shù)人都擋在了門外,那它的性能再強(qiáng)也沒有意義。Go 在設(shè)計(jì)上似乎就是刻意要跟 C++ 等復(fù)雜度不斷提升的語言區(qū)分開來:它語法極少,關(guān)鍵字也極少,就連功能都不多。

        這意味著 Go 語言很容易上手,稍微了解之后就能用它編寫出各種程序。

        Go 確實(shí)非常容易學(xué)習(xí)。之前就經(jīng)常聽人提到這一點(diǎn),但實(shí)際使用后我仍驚訝于它竟能快速提高工作效率。感謝 Go 語言、相關(guān)文檔和工具,我只用了短短兩天就編寫出了有趣且可以提交的代碼。
        —Rust 程序員對于 Go 語言的早期印象

        這里的重點(diǎn)就是“簡單性”三個字。當(dāng)然,簡單并不代表容易。可一門小而簡單的語言,學(xué)起來肯定要比大而復(fù)雜的語言要輕松。實(shí)現(xiàn)一種效果的方法并不多,所以高質(zhì)量的 Go 代碼看起來幾乎都是一個樣。這還帶來另一個好處:我們可以快速理解某項(xiàng)自己不熟悉的服務(wù)到底在做什么。

                
                  fmt.Println("Gopher's Diner Breakfast Menu")
                
                
                  for dish, price := range menu {
                
                
                      fmt.Println(dish, price)
                
                
                  }
                
              

        Go 的核心本體雖然很小,但標(biāo)準(zhǔn)庫卻非常強(qiáng)大。也就是說,除了 Go 語法之外,我們的學(xué)習(xí)曲線還必須考慮到標(biāo)準(zhǔn)庫這個部分。

        另一方面,把功能從語言轉(zhuǎn)移到標(biāo)準(zhǔn)庫,意味著大家只需要專注學(xué)習(xí)跟當(dāng)前開發(fā)需求相關(guān)的庫。Go 在設(shè)計(jì)上也充分考慮到大規(guī)模軟件開發(fā)需求,能夠有力支持大型代碼庫和開發(fā)團(tuán)隊(duì)。在這類場景下,新加入的開發(fā)者必須能夠快速上手。為此,Go 社區(qū)一直將程序的簡單、明確、通用和直接放在首位。

        使用 Go,我們可以快速完成工作。Go 是我用過的最高效的語言之一,它的座右銘就是:馬上解決實(shí)際問題。
        — Matthias Endler
        功能
        Rust 比其他幾種編程語言支持更多復(fù)雜性,所以對應(yīng)的實(shí)現(xiàn)范疇也更大些。
        — Devathon

        Rust 經(jīng)過專門設(shè)計(jì),包含多種強(qiáng)大且有用的功能,可以幫助程序員用最少的代碼完成更多任務(wù)。例如,Rust 的匹配功能就可快速編寫出靈活且富有表達(dá)力的邏輯:

                
                  fn is_prime(n: u64) -> bool {
                
                
                      match n {
                
                
                          0...1 => false,
                
                
                          _ => !(2..n).any(|d| n % d == 0),
                
                
                      }
                
                
                  }
                
              

        但也因?yàn)?Rust 在設(shè)計(jì)上考慮得多,所以學(xué)起來也就更困難一點(diǎn),特別是在起步階段。但沒關(guān)系,畢竟 C++ 或者 Java 也有很多東西要學(xué),甚至還無法提供內(nèi)存安全之類的 Rust 高級功能。所以批評 Rust 太過復(fù)雜的聲音實(shí)在沒啥道理:它在設(shè)計(jì)上就是在強(qiáng)調(diào)表達(dá)能力和豐富的功能,我們不可能在占了好處的同時(shí)又指望著它能那么簡單純粹。

        所以 Rust 當(dāng)然有自己的學(xué)習(xí)曲線。但只要跨過了這道難關(guān),后面就是一馬平川了。

        如果您已經(jīng)準(zhǔn)備好學(xué)習(xí)更復(fù)雜的語法和語義(以及更高的代碼可讀性門檻),并以此換取最高水平的性能表現(xiàn),那 Rust 甚至足以跟 C++ 和 D 分庭抗禮。
        — Dave Cheney

        Rust 和 Go 之間雖然彼此借鑒了一些功能(比如說泛型),但公平地講,Rust 的功能還是更勝一籌,Go 的功能相對要匱乏一點(diǎn)。

        并發(fā)性

        大多數(shù)語言都為并發(fā)編程(即同時(shí)執(zhí)行多項(xiàng)操作)提供某種形式的支持,但 Go 則是從頭開始就為此而設(shè)計(jì)。Go 不使用操作系統(tǒng)線程,而是提供一種輕量化的替代方案:goroutines。每個 goroutine 都是個獨(dú)立執(zhí)行的 Go 函數(shù),Go 調(diào)度程序會將其映射至控制下的操作系統(tǒng)線程之一。也就是說,調(diào)度程序可以非常高效地管理大量并發(fā) goroutine,且只須使用有限數(shù)量的操作系統(tǒng)線程。

        因此,我們可以在單個程序中運(yùn)行數(shù)百萬個并發(fā) goroutine,又不必?fù)?dān)心引發(fā)嚴(yán)重的性能問題。正因?yàn)槿绱?,Go 成為 Web 服務(wù)器和微服務(wù)等大規(guī)模并發(fā)應(yīng)用場景下的完全解決方案。

        Go 還為 goroutines 提供 channels,這是一種快速、安全、高效實(shí)現(xiàn)數(shù)據(jù)通信和共享的方法。Go 的并發(fā)設(shè)計(jì)水平確實(shí)很高,使用體驗(yàn)也相當(dāng)輕松愉快。

        一般來說,并發(fā)程序的設(shè)計(jì)難度很大,在任何語言中構(gòu)建起可靠且正確的并發(fā)程序都絕非易事。但由于在立項(xiàng)之初就考慮到這方面需求,所以 Go 中的并發(fā)編程機(jī)制已經(jīng)做得盡可能簡單且得到良好整合。

        Go 讓我們能更輕松地構(gòu)建起一個能精心解構(gòu)的應(yīng)用程序,這樣的應(yīng)用程序可以作為一組微服務(wù)進(jìn)行部署,并充分發(fā)揮并發(fā)性優(yōu)勢。Rust 也不是做不到,只是實(shí)現(xiàn)起來更難一些。從某種意義上講,Rust 更適合那些絕不允許因內(nèi)存問題而引發(fā)安全漏洞的程序員;但相應(yīng)的,他們在執(zhí)行某些對其他語言(包括 GO)來說較為簡單的任務(wù)時(shí),就得付出更多心力。
        —Sonya Koptyev

        相比之下,Rust 中的并發(fā)機(jī)制剛剛落地、還沒有最終穩(wěn)定,所以歡迎大家繼續(xù)關(guān)注這個活躍的開發(fā)方向。這樣也有好處,比如 Rust 的 rayon 庫就提供一種非常優(yōu)雅且輕量級的方法,能夠?qū)㈨樞蛴?jì)算轉(zhuǎn)換為并行計(jì)算。

        能有用于生成 goroutine 和使用 channels 的輕量級語法真的太棒了。這就是語法之力的直接體現(xiàn),種種小細(xì)節(jié)也讓 Go 的并發(fā)編程體驗(yàn)比其他語言好出一大截。
        —Rust 程序員對 Go 的早期印象

        雖然在 Rust 中實(shí)現(xiàn)并發(fā)程序可能不太容易,但仍然完全可行,而且這些程序還能獲得 Rust 精心設(shè)計(jì)的內(nèi)存安全保障。

        以標(biāo)準(zhǔn)庫的 Mutex 類為例:在 Go 當(dāng)中,我們可能會在訪問某些內(nèi)容前忘記獲取互斥鎖;但在 Rust 這邊則完全不需要擔(dān)心。

        Go 專注于把并發(fā)作為最核心的概念之一。這倒不是說我們就沒法在 Rust 中實(shí)現(xiàn)跟 Go 類似的并發(fā)性效果,只是實(shí)現(xiàn)難度對于程序員多少是種考驗(yàn)。
        —Dave Cheney
        安全性

        前文已經(jīng)提到,Go 和 Rust 都會以各自的方式防止各種常見的編程錯誤,特別是跟內(nèi)存管理相關(guān)的問題。但 Rust 走得更遠(yuǎn),可以說是不遺余力地保證大家不致搞出意料之外的安全紕漏。

        Rust 的編譯器簡直是嚴(yán)格到迂腐,它會檢查我們使用的每個變量、引用的每個內(nèi)存地址。它避免了潛在的數(shù)據(jù)競爭情況,還會通知你存在未定義行為。在 Rust 的世界中,并發(fā)和內(nèi)存安全問題幾乎不可能出現(xiàn)。
        —為什么選擇 Rust?

        也就是說,Rust 的編程體驗(yàn)跟幾乎所有其他語言都有所不同,而且在剛剛接觸時(shí)可能相當(dāng)具有挑戰(zhàn)。但在不少開發(fā)者看來,這份付出顯然物有所值。

        對我來說,Rust 最大的優(yōu)勢就是編譯器成了我的好助手,它不會放過任何檢測得到的 bug(說真的,有時(shí)候我感覺它就像會魔法)。
        —Grzegorz Nosek

        包括 Go 在內(nèi),很多語言也提供幫助程序員避免錯誤的工具,但 Rust 把這種效果提升到了新的水平。很多不正確的程序甚至根本沒辦法編譯。

        在 Rust 中,各種庫工具都能幫助程序員防止用戶犯錯。Rust 允許我們指定一段數(shù)據(jù),然后保證它不歸屬于任何其他事物、也不會被任何其他事物所篡改。我想不起以往還有哪種語言會提供這么多防止意外誤用的工具,這種感覺堪稱美妙。
        — Sam Rose

        “與借用檢查器作斗爭”是 Rust 新人們必須要過的一關(guān),但在大多數(shù)情況下,檢查器并不是真正的敵人。它發(fā)現(xiàn)的問題確實(shí)是代碼中的真實(shí) bug(或者至少是潛在 bug)。它可能迫使我們從根本上重構(gòu)自己的程序來避免此類問題——如果各位確實(shí)把正確性和可靠性當(dāng)作首要任務(wù),那這種嚴(yán)格要求顯然是件好事。

        換個角度想,不改變編程方式的新語言,能叫新語言嗎?而且在使用其他語言時(shí),Rust 教會我們的安全思維同樣意義重大。

        如果大家選擇了 Rust,往往是因?yàn)橐褂盟峁┑谋U闲栽O(shè)計(jì):關(guān)于空指針 / 數(shù)據(jù)競爭的安全性、可預(yù)測的運(yùn)行時(shí)行為,還有對硬件的完全控制。如果這些對你來說毫無意義,那確實(shí)沒必要非得使用 Rust。畢竟這些好處背后是有代價(jià)的:上手很費(fèi)勁。你得改掉壞習(xí)慣并掌握新概念。剛開始的時(shí)候,大家都會被借用檢查器折磨得死去活來。
        — Matthias Endler

        上手 Rust 編程模型的實(shí)際難度,可能取決于大家之前用過哪些其他語言。Python 或者 Ruby 程序員可能覺得 Rust 限制太多,但其他人可能覺得這種清晰明確的約束也不錯。

        如果你是一名 C 或者 C++ 程序員,曾經(jīng)花幾個禮拜在語言中查找內(nèi)存安全 bug,那你一定會愛上 Rust。于是“跟借用檢查器作斗爭”就變成了“編譯器還能這么用?爽!”
        — Grzegorz Nosek
        規(guī)?;?
        如今的服務(wù)器程序包含著數(shù)千萬行代碼,由成百上千名程序員編寫而成,并且?guī)缀趺刻於荚诟?。Go 在設(shè)計(jì)和開發(fā)上,充分考慮到了此類環(huán)境下的工作效率提升需求。Go 的設(shè)計(jì)考量因素包括嚴(yán)格的依賴項(xiàng)管理、軟件架構(gòu)隨系統(tǒng)增長的適應(yīng)性,還有跨組件邊界的健壯性。
        — Rob Pike

        當(dāng)大家獨(dú)自或者在小團(tuán)隊(duì)中解決問題時(shí),要選簡單的語言還是豐富的語言純屬個人喜好。但隨著軟件規(guī)模的擴(kuò)大、復(fù)雜度的提升、團(tuán)隊(duì)的膨脹,兩類語言之間的差異才開始真正顯現(xiàn)出來。

        對于大型應(yīng)用程序和分布式系統(tǒng),代碼執(zhí)行速度的重要性往往低于開發(fā)速度:像 Go 這種刻意強(qiáng)調(diào)精簡設(shè)計(jì)的語言能夠縮短開發(fā)新手的適應(yīng)時(shí)間,也讓他們能更快參與到大型代碼庫的貢獻(xiàn)當(dāng)中。

        使用 GO 語言,初級開發(fā)者往往更容易提高工作效率,但中級開發(fā)者則更難引入復(fù)雜的抽象并因此導(dǎo)致問題。正因?yàn)檫@種特性,在企業(yè)軟件開發(fā)領(lǐng)域,Rust 的吸引力往往不及 Go。
        — Loris Cro

        在涉及大規(guī)模軟件開發(fā)時(shí),明確易讀總是比精巧優(yōu)雅更重要。Go 的局限性實(shí)際使其比 Rust 等更復(fù)雜、更強(qiáng)大的語言,要更適應(yīng)企業(yè)和大型組織的需求。

        Rust 與 Go:差異之處

        雖然 Rust 和 Go 都是高人氣且得到廣泛應(yīng)用的現(xiàn)代語言,但二者間并不是真正的競爭對手,因?yàn)樗鼈兯嫦虻挠美梢哉f完全不同。

        Go 的整個編程方法就跟 Rust 完全不同,這些特性一方面特別適合某些人,但另一方面也會徹底激怒某些人。這很正常,因?yàn)槿绻?Rust 和 Go 都在以基本相似的方式解決基本相同的問題,那我們干嘛還需要兩種獨(dú)立的語言?

        那么,我們能不能從 Rust 和 Go 采取的方法入手,解讀它們各自的本質(zhì)呢?下面就一起來試試。

        垃圾收集

        “要垃圾收集,還是不要垃圾收集”永遠(yuǎn)是個沒有正確答案的問題。一般來說,垃圾收集和自動內(nèi)存管理能幫助我們快速、輕松地開發(fā)出可靠且高效的程序。所以對某些開發(fā)者來說,這些都是必不可少的功能。

        但也有人認(rèn)為,垃圾收集和它帶來的性能開銷與全局暫停,會導(dǎo)致程序在運(yùn)行時(shí)的行為變得不可預(yù)測,同時(shí)引入不可接受的延遲。這話當(dāng)然也有道理。

        Go 跟 Rust 這兩種語言可以說截然不同。盡管二者都可以被簡單描述成系統(tǒng)語言或者 C 的替代品,但它們的目標(biāo)和應(yīng)用場景、語言設(shè)計(jì)風(fēng)格與功能優(yōu)先級確實(shí)差異巨大。垃圾收集就是一大核心差異因素。Go 中的垃圾收集讓語言變得更簡單、更小巧也更易于理解。Rust 不設(shè)垃圾收集則讓它速度極快(這一點(diǎn)特別適合那些不僅要求高吞吐量、更要求低延遲的開發(fā)者),同時(shí)也實(shí)現(xiàn)了 Go 根本不可能做到的一系列功能與編程模式(至少是在不犧牲性能的前提下)。
        — PingCAP
        貼近硬件

        計(jì)算機(jī)編程的發(fā)展史,可以說是一段日益復(fù)雜的抽象發(fā)展歷程。它讓程序員們既能解決問題,又不用太多關(guān)注底層硬件的實(shí)際運(yùn)行方式。

        這種設(shè)計(jì)讓程序更易于編寫、更具可移植性。但對于其他一些程序來說,訪問硬件及精確控制程序的執(zhí)行方式反而更加重要。

        Rust 的目標(biāo)就是讓程序員能“貼近硬件”,奪回更多控制權(quán);而 Go 則抽象掉了架構(gòu)細(xì)節(jié),讓程序員更貼近問題。

        兩種語言各有不同的應(yīng)用范圍。Go 擅長編寫微服務(wù)和典型的“DevOps”任務(wù),但它并不屬于系統(tǒng)編程語言。Rust 在強(qiáng)調(diào)并發(fā)性、安全性及 / 或性能的任務(wù)中更為強(qiáng)大,可學(xué)習(xí)曲線也確實(shí)比 Go 更陡峭。
        — Matthias Endler
        性能為先

        其實(shí)對大多數(shù)程序來說,性能的重要性是不及代碼可讀性的。但如果某些項(xiàng)目確實(shí)是以性能為先,那 Rust 中的很多設(shè)計(jì)權(quán)衡,將幫助大家把代碼的執(zhí)行速度一路推向極限。

        相比之下,Go 更關(guān)心代碼簡單性,甚至愿意為此犧牲一些運(yùn)行時(shí)性能。但 Go 的構(gòu)建速度無與倫比,這對大規(guī)模代碼項(xiàng)目來說往往更加重要。

        Rust 的執(zhí)行速度優(yōu)于 Go。在基準(zhǔn)測試中,Rust 速度確實(shí)更快,某些情況下甚至能快出一個數(shù)量級。但在選擇 Rust 語言之前,請先認(rèn)清一點(diǎn):Go 在多數(shù)基準(zhǔn)測試中也沒有落后太多,而且也仍然保持對 Java、C#、JavaScript 和 Python 等語言的性能優(yōu)勢。
        如果你需要的是頂級性能,那么在這兩種語言中任意選擇都可以,速度表現(xiàn)絕不會令人失望。另外,如果你正在構(gòu)建一款處理高強(qiáng)度負(fù)載的 Web 服務(wù),而且要求能夠縱向 / 橫向靈活擴(kuò)展,兩款語言也都能滿足需求。
        — Andrew Lader
        正確性

        另一方面,如果不強(qiáng)求程序永不出錯,那取舍以會不同。大多數(shù)代碼都不會考慮到長期使用,但某些程序也確實(shí)在生產(chǎn)環(huán)境中多年運(yùn)行。

        面對這些現(xiàn)實(shí)情況,也許我們有必要投入一點(diǎn)額外的時(shí)間,來開發(fā)并保證程序能夠正確、可靠運(yùn)行,且未來不致引發(fā)沉重的維護(hù)負(fù)擔(dān)。

        Go 和 Rust 都能幫助大家編寫出正確的程序,只是具體方式各有不同:Go 提供出色的內(nèi)置測試框架,而 Rust 則專注通過借用檢查器消除運(yùn)行時(shí) bug。

        我的看法是:對于明天就得發(fā)布的代碼,用 Go;如果是未來五年內(nèi)必須能穩(wěn)定運(yùn)行的代碼,那么選 Rust。
        — Grzegorz Nosek

        雖然 Go 和 Rust 都足以支撐起嚴(yán)肅的開發(fā)項(xiàng)目,但大家最好還是能充分了解它們的各種特性和優(yōu)勢。

        總之,別人的想法并不重要:只有你自己能決定哪種編程語言更適合你的團(tuán)隊(duì)及項(xiàng)目需求。

        如果你想加快開發(fā)速度,比如說你有很多不同服務(wù)需要編寫,或者開發(fā)團(tuán)隊(duì)本身規(guī)模龐大,那么 Go 語言肯定是正確答案。Go 特別關(guān)注并發(fā)性設(shè)計(jì),而且會敏銳地揪出不安全的內(nèi)存訪問行為(Rust 也可以),但又不強(qiáng)迫你逐一管理每處細(xì)節(jié)。
        Go 快速而強(qiáng)大,但它的核心亮點(diǎn)還是幫助開發(fā)人員擺脫困境、專注于簡單性和統(tǒng)一性。在另一方面,如果你需要竭盡全力發(fā)揮每一絲性能空間,那 Rust 才是最理想的選擇。
        —Andrew Lader

        總結(jié)希望這篇文章能幫助大家理解 Rust 和 Go 的各自亮點(diǎn)。如果可能的話,各位最好能多少體驗(yàn)一下這兩種語言,因?yàn)樗鼈冊谌魏渭夹g(shù)道路上都非常有用,哪怕對業(yè)余編程愛好者也是如此。

        但如果您的時(shí)間只搞認(rèn)真鉆研一門語言,那請千萬先把 Go 和 Rust 各自的專長和傾向性搞清楚,之后再做選擇。

        當(dāng)然,關(guān)于編程語言的知識只是成就一名成功軟件工程師的很少一部分。除了編程之外,工程師們還得精通設(shè)計(jì)、工程、架構(gòu)、溝通和協(xié)作。只要大家能把后面這幾樣做好,那無論你選擇哪種編程語言,都將成為一名出色的軟件工程大牛。

        參考鏈接 https://bitfieldconsulting.com/golang/rust-vs-go https://news.ycombinator.com/item?id=37107052 https://thenewstack.io/developers-most-likely-to-learn-go-and-rust-in-2023-survey-says/ https://blog.rust-lang.org/2023/08/07/Rust-Survey-2023-Results.html 聲明:本文由 InfoQ 翻譯。


        往期推薦


        我是 polarisxu,北大碩士畢業(yè),曾在 360 等知名互聯(lián)網(wǎng)公司工作,10多年技術(shù)研發(fā)與架構(gòu)經(jīng)驗(yàn)!2012 年接觸 Go 語言并創(chuàng)建了 Go 語言中文網(wǎng)!著有《 Go語言編程之旅 》、開源圖書《 Go語言標(biāo)準(zhǔn)庫 》等。


        堅(jiān)持輸出技術(shù)(包括 Go、Rust 等技術(shù))、職場心得和創(chuàng)業(yè)感悟!歡迎關(guān)注「polarisxu」一起成長!也歡迎加我微信好友交流: gopherstudio


        瀏覽 54
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 把雪白的岳弄的好爽 | 无码中文字幕一区二区免费蜜桃 | 美女久久久久 | 偷拍久久久 | 国产亲子伦视频一区二区三区在线 |