撰稿 | 云昭
出品 | 51CTO技術棧(微信號:blog51cto)
眾所周知,由于其根源于 Mozilla,Rust 在歷史上與系統編程聯系在一起,它對安全性、速度和并發性的承諾,使其在基礎設施層面得到了廣泛采用。這種地位的上升引發了一個有趣的問題:Rust 在傳統上由動態語言主導的領域是否擁有更高的地位?
近日,一場匯聚了新興語言的主要開發者的會議P99 CONF ,為我們帶來了Rust與Zig如何相互借鑒,并讓與會者們參與了挑戰C++、Go甚至JAVA等主流語言的探討。且讓我們一探Rust與Zig的未來。
一、Zig可以借鑒Rust,反之亦然世界上偉大的事物往往是完全開放,既可以和而不同,又可以相互借鑒。Zig與Rust之所以快速成為全球編程社區的“寵兒”,也是做到了開放與借鑒。
1.Zig學習Rust哪些?Bun的創建者Jarred認為,Zig可以Rust那里引進“有限的編譯時概念”,比如在各種類似作用域的情況下的一些借用檢查器。此外,Zig安全方面還比較欠缺,兩個明顯的例子就是,還可以返回指向堆棧內存的指針,例如堆棧分配的緩存區,這都是不應該做的。
Zig語言還非常新,但誕生之初就懂得借鑒。比如向Go借鑒了延遲(defer),即延遲鍵盤和語言。與Go實現的區別在于,它是針對每個作用域的,而不是針對每個函數的。在 Go 中,defer 會將其附加到函數的末尾,而對于 Zig 來說,它位于作用域的末尾。這通常就是開發者進行資源清理的方式。
但Zig的延遲做的還不夠好, 至少有某種形式的析構函數,因為它很容易被忘記。“有時我確實希望有構造函數和析構函數……但我的心情很復雜。”
2.Rust羨慕Zig什么?Rust主要開發者Carl,則表示了Rust對于Zig編譯速度的羨慕。“Zig 的編譯速度肯定要快得多。Rust 肯定會從中受益。”
Rust目前的一個痛點就是:一旦你擺脫借用檢查器而使用 Rust 進入不安全代碼,它就很不符合人體工程學,而事實上,在編寫nice的不安全代碼方面,Rust其實有許多地方可以改進。Carl表示:我們編寫的不安全代碼比典型的應用程序開發人員多得多,因為我們正在構建這些類型的原語。Zig在這方面可以給Rust以靈感。
P99 CONF 的長期支持者Glauber,認為 Zig 有兩件事可以讓 Rust 受益匪淺。第一個是comptime。comptime 是Zig一個非常好的特性,即在編譯期引入自身作為膠水語言來生成代碼的能力,甚至被Glauber稱為天才之舉,“我希望每種語言都有這樣的功能。
C++中的模板系統與 comptime 相比……根本不在同一個級別。”
可能很多人不太熟悉comptime, 簡單來說,它允許開發者在編譯時評估任意代碼。許多語言都有類似模板的語法,然后還有一些其他變體,一些其他方式來具有編譯時標志、功能和參數。這也是類型系統的工作原理。例如,標準庫中的 ArrayList 類型接收 comptime 類型參數,然后就有一個該類型的切片。這有點像編譯時的duck-typing類型。
舉例來說,Zig用它來生成用于源映射解析的查找表。sourcemaps 使用這種編碼 VLQ。“如果我們生成此查找表,則源映射編碼速度將比以前快 18%。最初,我們是在運行時執行的。”Zig 使其變得非常簡單,因為只需傳遞關鍵字即可。頂級作用域中的任何內容都是 comptime,否則,就可以將其傳遞到作用域中的關鍵字 comptime 中。
第二個,是 Rust交叉編譯到不同的平臺,是一個非常痛苦的事情。這方面Go 做得非常好, Zig 也比 Rust 做得更好。
交叉編譯方面,Carl還透露了Zig的情況。“現在在 Bun CI 中,我們在 linux 機器上為所有不同的平臺、每個 Zig 部分構建每個目標文件。因為每臺機器都有大量內存以使其編譯速度更快。因此,我們在 Linux 上構建所有 Zig 代碼,即使它是針對 mac OS 的。”
二、用C的人為什么討厭Rust,喜歡ZigRust 一直是注重性能的 P99 CONF 社區的寵兒。即使我們以 C++、Go 甚至 Java 的令人印象深刻的性能成就案例研究為特色,討論也不可避免地轉向“但為什么不是 Rust?”
很多人習慣于C,將C用于高效工作,因為C語言確實讓你的移動速度快得令人難以置信(直到出現錯誤)。他們選擇Rust,嘗試像C一樣編寫Rust,最終都會遇到Rc<RefCell<...>>,unsafe{...}等。
這種大量的錯誤報告和“調試地獄”會帶來非常強烈的負面反應。
但這并不意味著Rust太難了,其實有能力用C編寫生產軟件,就絕對有能力使用Rust。更多地在于,“當C方式對我很有幫助時,我不愿意學習Rust方式。”
這反而是Zig的利基市場。
如果您已經了解 C,您可以在幾天內學習 Zig,并且比 C 更有效率。在我看來,這就是 Zig 的價值主張。它與 C 非常相似,您的大多數模式和根深蒂固的經驗都可以利用。你學習了 Zig 的 comptime,然后,你就掌握了帶泛型的 C 語言。您可以毫無障礙地依賴現有的 C 項目和庫。Zig 是“我在 C 語言中很有生產力,但想要更好的功能”語言。
三、Java開發者不妨考慮學Rust“Rust并不是太困難。我是一個巨菜的菜鳥,連我都可以在大約一個月內寫出一些不錯的Rust。”
雖然舊版 Java 很簡單,但大部分時間都花在學習庫、構建系統或非常復雜的應用程序服務器上。這3個部分非常復雜。編寫 Spring MVC Web 應用程序非常復雜。
“我們公司遷移到 Rust,花了大約 1 個月的時間才適應 Rust,無需處理 C 指針、內存映射等低級內容。”
部署 Rust Web 應用程序比處理 Java 應用程序服務器和 WAR 容易得多。為什么Java應用服務器有這么多bug?
20 多年過去,它們仍然無法獲得諸如重新加載而不泄漏或數據庫連接池可靠而不掛起連接之類的東西。
“JDBC 的編寫方式使得池無法強制關閉卡住的連接;卡住的連接會隨著時間的推移而累積,直到服務器掛起。”
這表明Java J2EE應用服務器的整個概念是錯誤的。每個曾經使用過websphere的人,web logic都會把他們折磨到“地獄”。即使是最小化的 Tomcat 也遠未消除錯誤。JVM 本身正在崩潰。“我還沒有看到任何 Java 應用程序后端或 GUI 不會因為內部 JVM 錯誤而崩潰。”
Rust 需要的內存比 Java 少 10 倍,速度比 Java 快 4 到 10 倍,編譯失敗很快就會得到修復。不需要應用程序服務器和巴洛克式構建工具(變形的工具)。Rust 就可以,無需開始用 Java 編寫新的應用程序。
Rust 有相當高級的庫,如 Rocket.rs (rust) 和微型 Web 框架,如 scalatra.org (scala),這兩種類型都非常容易上手。而且使用起來也要容易得多:所有內容均已鍵入,并且類型信息也可用作文檔。
四、Rust在后端項目的軟肋也有一種觀點認為,Rust不適合大型項目。因為Rust 項目是 AOT 編譯的二進制文件,需要不斷維護才能使其不斷變化的包保持最新。此外,項目越大,linting 越慢,分析器越慢,構建時間也越慢。
也就是說,Rust 的借用檢查器并不是大型項目中真正令人頭疼的問題。然而,你需要學習如何移動、復制或借用內存的各種方法以及不自然的生命周期語法需要很長時間才能深入理解這些背后的真相。