Go語言的成功也預示著Rust的成功
從整體的角度來看Go,很難理解他是怎麼取得這麼大的成功的。從理論的角度上來說Go是一門非常糟糕的語言,就算是和C++或者Ada之類舊語言相比也是這樣。它缺乏大量的編譯時的檢查和編譯時的邏輯,它缺乏銷毀邏輯導致許多樣板文件和運行時錯誤。它的界面不是很有表現力。它具有一等公民數據結構(slices和maps),不能使用語言本身作為庫進行複制。
在許多不需要易變性的情況下,它強制用戶進行易變性。它附帶了一個偽依賴管理器,它缺乏獨立項目的獨立版本控制。與大多數其他流行的系統編程語言(即C、C++、Ada、Fortran和Rust)相比,它的速度非常慢。
這就是我現在能想到的,很容易就能給你們展示的東西。一旦你深入研究go,你會發現它會做出一些固有的錯誤設計選擇,它是為1980年而不是2020年設計的語言。
儘管如此,就像任何曾經使用過go的人都能告訴你的那樣,這是一種非常好的語言。如果我被困在一個只有三種編程語言的島上,我想go會成為其中之一。
儘管存在所有的缺陷,但它允許您編寫性能良好的相對無錯誤的代碼。向Go程序添加依賴項通常比向C++程序添加依賴項要順利得多。
為什麼Go 是棒的
這讓我處於一個非常奇怪的位置。一方面,我可以談談Go 有多可怕。另一方面, Go 顯然是一種非常好的語言。
為了弄清楚為什麼是這樣的,我們依然需要回到程序員解決問題的角度,把語言作為工具來看。
很多現代世界的問題看起來都是圍繞著有效網絡通信,圍繞安全地利用所有硬件線程以及更容易的和部署展開的。
最後,漸漸有了一個穩定的趨勢,良好的開源庫滲透到我們的生活中,其中大多數是簡潔和簡單,適合單一目的。大多數Node 或Python 項目都有數百個這樣的依賴項,而大多數C 和C ++ 代碼庫都有十幾個。C 和C ++ 缺乏任何標準化的包管理,因此庫往往是無所不包的整體(參見QT 和Boost ),而它們添加新的依賴項非常耗時。
開源庫是現代開發人員生涯中的重要組成部分,但所有流行的系統編程語言都缺乏包管理。
從這個角度來看,Go有一些中心特徵,這些特徵非常讓人驚嘆,以至於它們把所有不好的一面都掩蓋了。
- Go 的實用程序允許您輕鬆下載和使用包。
- 靜態編譯使得在不同環境之間移植代碼,並且可以很容易地建立開發環境。
- 本地異步I/O 機制允許您可以輕鬆編寫高性能的網絡代碼。
- 內置通道允許在[g|c]oroutines 之間輕鬆實現和相對安全的數據傳輸。
- 標準庫和包生態系統包含了開發人員能夠需要的大多數庫。
- 對於幾乎所有的使用案例來說,它“足夠快”。似乎在如Python 和Node 這些易於使用的單線程語言,甚至是像C++ 和C 這樣的古老而又快速的龐然大物之間找到了一個最佳位置。
或者,說白了, Go 是一種專為開源庫,大規模並行和網絡計算而設計的語言。
其他流行語言則缺少這三個類別中的一個。
Go的所有剩餘問題源於三種設計選擇:
- 垃圾收集,而不是為其所有資源定義編譯時間的生命週期。這會損害性能,刪除有用的概念(如移動語義和析構函數),並削弱編譯時錯誤檢查功能。
- 缺乏不可變性,除了少數(本機)類型之外。
- 缺乏泛型
若解決這些問題,Go無疑會成為未來的語言。但是,由於各種問題,有些與先前的設計決策有關,有些又與設計師的意見有關,其中大部分都未解決。
例如,泛型可能會在2.0上實現,但是當前的實現與其他特徵(比如接口)重疊,同時使用起來又煩惱並且缺少特徵(比如,不能用作返回類型)。
或許我們可以找到一種“檢查”所有正確語法的語言,又不用忍受那些糟糕的設計決策。
再來看看Rust 語言
Rust 恰巧是一門解決了Go 所有問題的語言。
基於它的隱式移動語義和借用檢查功能,使它在資源管理領域最終成為了最安全,最快速並且也最容易使用(這裡是相對來說。比如目前借用檢查比較難用,用過的都知道)的語言。它在編譯期間就可以捕獲大多數錯誤。
模板和特性(traits)組合給了它接近於C++的編譯時編程能力,甚至某些方面更勝一籌。
最後,Cargo 也是最好的包管理系統之一,它可以讓你更容易地使用各種實用的公共庫,並且有內建版本號和項目隔離特性。
換句話說,Rust的極大成功就是基於它更好地解決了Go存在的問題。
但是,Go 做得無比正確的事又有哪些呢?
- go get和go mod與Cargo非常匹配
- cargo build默認使用靜態編譯路由,這一點和go build基本一致
- 重點來了,Rust目前還沒有原生異步i/o機制。但是據說這個機制馬上就有了。這個機制與goroutine所提供的功能差別很大,而是更像我們所熟知的Node和Python中所使用的語法。
- Rust 不僅提供了線程之間的原生管道(channel)支持,它提供了一套健壯的編譯時線程安全檢查機制。這意味著無論你使用何種數據共享機制都不存在並發錯誤的風險。
- 儘管Rust 是一門年輕得多的語言, Rust 的標準庫和go 的差不多一樣豐富,當然除了(再次除了)一些沒有的異步網絡功能之外。當前Rust 的包(package)生態系統和Go 的一些方面很像。
- 最後是效率方面。在大部分的場景下, Rust 只比C 和C++ 稍慢那麼一丟丟。但是對於它的設計方向來講這只是一個“臨時性的”折扣。Go 將永遠受累於缺乏編譯時邏輯和基於GC 的設計。因此,Go 和Rust 之間現有的巨大效率差只會越拉越大。
Go 的影響
一旦async/await 特性被合併到Rust的穩定版中,我認為Rust就完全超越Go了,確切地說,在任何方面!(譯者註:借用檢查仍舊是導致Rust難用的一個原因,最好是有更多的隱式借用或更好的方案)
我認為直到將Rust真正應用於產品中,人們才會認識到Rust在測試,調試和程序崩潰等方面為你節省了多少時間。
Rust和Rust相關的概念進入編程世界越多,人們就會越熟悉它的語法和概念,因此進入的門檻也就越低。
我認為Rust已經走過了它生命中最危險的時期,它已經逐漸地被接受並作為主要開發語言。更進一步講,當與其它語言在各方面比較時,它幾乎是完胜其它語言(編者:各種語言特性方面確實是,但易用性上還差些)。簡單講,在大多數情況下,Rust應該是更好的選擇。
但是人的惰性是不可忽視的一個問題,Rust很難被大家廣泛採用的阻力,來自於如何說服開發者轉換到它上面。
這裡,我認為Go突然爆發的原因,也可以同樣應用於Rust身上。Rust現在越來越接近全面爆發了(譯者註:隨著生態成熟,也快到引爆點了)。
一些希望有“現代編程範式”的C&C++開發者,也會喜歡上Rust。
同時,對於一些希望從腳本語言轉到系統編程語言上的那些人來說,這也是最好的選擇,你不但擁有了安全和性能,你還仍舊可以使用包管理工具和熟悉的語法。
無論如何,這是我的預測,一旦async&await 加入到語言中,我們將有大量的網絡應用程序開發人員湧入Rust。
網絡依賴的高性能開源軟件,如內存緩存,和反向代理,將開始逐步走向成熟。很多這樣的項目已經在go的生態系統中出現了。
一旦這些開發人員在網絡和並發性方面嗅到了Go 的簡易性,再加上C++ 的速度,抽象能力和資源管理,以及頂級的編譯時安全性……
隨後,Web 開發人員和企業團隊將跟隨宣傳。
一切就猶如打開了防洪閘門,不可阻擋。
George Hosu https://github.com/George3d6我很擅長命名東西,並清楚如何使緩存無效。