#分享 Rust程式語言

2020年5月3日 12:15
最近因為看到蠻多板上的同學或工程師推薦學C,所以讓我想推廣一下一個跟C, C++有差不多效能,但不需要擔心記憶體使用問題,又不需要garbage collector的程式語言Rust。它是第一個我看到同時上至網路服務,下至CLI程式、甚至作業系統核心都能撰寫的高階語言。 Rust是Mozilla Research (Firefox背後的公司的研究單位)在2010年發表的程式語言。主要發明它的背景有幾個原因,1) 記憶體管理問題,2) Thread safety。記憶體問題包含:Use after free, null pointer dereference, using uninitialized memory, double free, buffer overflow等等。Thread safety則是常見的:deadlock, race information loss due to race condition, etc. 首先針對記憶體管理問題。傳統上,記憶體管理方式分為兩大類別:1) 手動管理,2) 讓garbage collector管理。手動管理方式最大的優點是你擁有完全控制,但同時也是最大的缺點。從Mozilla、Microsoft公開的統計資料都顯示,大型C, C++ codebase中,很大一部分的安全性漏洞都源自於記憶體使用上的問題(Reference 1, 2)。Debug加上修復這些在production的問題,是非常耗時且昂貴的。 至於garbage collection,優點是軟體工程師不太需要擔心記憶體管理的問題,因為garbage collector會像一個跟在你程式身邊的清道夫,一段時間會出來大清掃一次,自動把不再需要的記憶體區塊還給作業系統。然而,這樣的便利性是有代價的。因為在程式執行時,進行大清掃不可避免地會影響到效能。 Rust選擇了第三個方式來做記憶體管理,Ownership。藉由Rust Compiler來強制施行(基本上就是給你的程式compile不過)以下三個原則,來做到memory safety,但又不需要garbage collector: 1) 任何Rust內的值,都屬於一個變數,稱為它的owner 2) 任何時候,每一個值都只有一個owner 3) 當一個owner goes out of scope,對應的值會被dropped (或freed) 基本上,你可以想像成,Rust compiler會在compile你的程式碼時,利用上述三個原則,來自動插入對應的memory allcation跟deallocation程式碼而不需要你介入。 再來,針對Thread safety。傳統上,有幾個處理方式:1) 手動管理 (如C, C++),2) runtime exception (如Java,3) 直接不給你multithread lol (如CPython中的GIL, global interpreter lock)。Rust再次有點反骨的,採取了跟這些不太一樣的方式:1) 利用前述的ownership原則,沒有任何值會同時有兩個owners,所以避免了race condition。2) 每個owner被限制只在一個thread上活動,3) 除了owner可以改變這個值外,其他人都只能唯讀這個值 (Rust中稱為immutable borrow)。 作為一個現代的程式語言,如果單單只有上述這些優點是還不夠的。Rust的生態系統還為開發者們提供了許多便利的工具: 1. Rustup: 管理local Rust toolchains的工具。可以讓你方便地安裝不同版本的Rust,並在它們間切換。 2. Rust語言本身就提供Unit test, integration tests以及benchmarking的功能。所以你可以馬上開始撰寫production quality的程式。 3. Cargo: 有點類似Python中的pip及Pypi。Cargo是Rust一流的package manager。有寫過一定規模程式的工程師們,都可以體會dependency management是一個非常重要但又十分枯燥乏味的瑣事,因為必須考量它們彼此間的相容性,又要不定時的更新。Cargo以及其相應的Rust package registry網站,
4. Built-in formatter:有寫過任何沒有built-in格式formatter的程式語言 (如C, Java等等)的朋友,就可以體會當某個同事沒有使用大家共通的程式碼排版設定時,他的Pull request或code review就會出現一堆五花八門跟實際功能無關的改動,例如:移動大括號的位置,或者把一行長的程式碼分隔變成好幾行等等。Rust跟Go一樣,都自帶built-in formatter,rustfmt可以自動把你所有的程式碼根據官方建議的統一風格來排版。 5. 自動文件產生:對工程師來說是必要的工具,就是利用程式中的註解自動產生說明文件的rustdoc。除了產生格式統一且方便搜尋的文檔外,它還可以自動運行文件中的sample code,以確保你的說明文件跟實際的程式碼是搭得起來的。 6. Foreign function interface (FFI):Rust跟C之間可以互相呼叫,而且沒有任何效能影響。換句話說,你可以在Rust程式中,使用一個C library,或是在一個C程式中,呼叫一個Rust library中的function。 最後,Rust現在被用在業界的哪些地方呢?Rust的創建公司Mozilla就用它重寫了Firefox瀏覽器中的重要元件;Amazon則利用Rust能夠跟低階軟硬體對接的特性,寫出輕量化虛擬機框架Firecracker;Dropbox則是把Rust用在客戶端運行的同步引擎及後端伺服器的壓縮演算法裡;Microsoft也正在實驗如何利用Rust提供的額外安全性,來重寫微軟作業系統核心裡的部分元件。 如果之後,有新專案可能需要類似C或C++的效能,但你又不想處理隨之而來的問題的話,試試看Rust吧!:) Ref 1:
Ref 2:
Ref 3:
34
留言 33
文章資訊
4 篇文章24 人追蹤
Logo
每天有 7 則貼文
共 33 則留言
長庚科技大學
推 好猛跟用心!
國立臺灣科技大學
rust還是太混亂了 C依然具有高度不可取代性
B2 哈哈,沒有人提議要完全取代C哦。像Linux kernel及一些battle tested的套件庫,重寫實在沒什麼必要。但是新的程式或libraries,其實如我文中所說的,還蠻多大公司開始考慮Rust的。如果我記得沒錯,Linux核心裡面有一個新的檔案系統也是用Rust撰寫的。 Rust不是最容易學的語言,所以可能讓你覺得它很混亂。不過,在某些需要高度安全或穩定性的領域,它目前是有一群不小的追隨者的,如Blockchain中,就有很多應用哦!
國立臺灣科技大學
B3 可能是我看的太習慣kernel source code跟寫C寫太久了吧XD rust的風格我真的沒辦法接受
B4 我自己也還在學習跟習慣中,畢竟我也是從Java跟C開始學的哈哈!
朝陽科技大學 資訊管理系
未來找時間可以嘗試看看XD
國立中正大學
蠻潮的
匿名
此帳號疑似異常
官方正在進行身份確認
感覺還得觀看一陣子 看可不可以達到目前golang 的生態
B6 B7 有空一起試看看! B8 Golang因為Docker及k8s的關係,加上有Google的加持。真的是很熱門!如果你想撰寫的程式不需要interface低階的OS kernel或硬體,然後又可以忍受garbage collection帶來的效能影響的話,那Go真的是比Rust好學好寫得多。 不過,也因為Golang永遠有一個runtime在負責GC以及goroutine scheduling的關係,它沒辦法拿來寫OS kernel。另外一個Golang對於低階OS API比較應付不來的例子,是在Docker的核心引擎runC裡,在進入namespace的部分被迫要用C寫,即使Docker剩下的部分幾乎都是Go code。主要的原因,就是因為Goroutine scheduler會動態地把正在運行的goroutines分配到數個OS threads上,造成無法確定進入namespace的thread是哪一個的問題。 In summary,我想比較能跟Go比較的,應該是Java。Rust則是設計來解決傳統上寫C, C++常遇到的記憶體管理,thread safety等等問題。當然兩者都可以拿來寫CLI或web services之類的啦lol
國立高雄第一科技大學 資訊管理學系
我也滿期待 Rust 的,在等 deno 正式發布後看看情況如何
國立臺灣大學
想請問如果想走web的話要學golang還是Rust比較好
國立嘉義大學
B11 golang
B11 B12 我想你指的Web應該是backend web services對吧?在大多數情況下,我想web service都可以容忍garbage collection帶來的delay,所以golang是一個好選擇,因為它容易撰寫,速度也夠快。不過,當你的web service需要極致的performance的話,Rust就會是更好的選擇。這也是為什麼Dropbox在它的後端,負責壓縮演算法的元件就是用Rust寫的(
總結來說,用Golang開始,然後benchmark找到bottleneck(s),再考慮以Rust重寫那部分,然後可以利用cgo等等來實現golang呼叫Rust liraries/functions。
國立臺灣科技大學
我是 B2 B4 現在其實有好幾個side project在run都用C 不用C我真的寫不下去XD
B14 除非有技術上需求,不然當然是寫起來開心最重要哈哈
國立臺灣大學
我還是 Go 跟 C++ 派 C++ 有 smart pointer,有 async 有 future,有 coroutine,有 module,有 template constraint,工作中 core library 都用 C++ Go 是 cloudnative 的原生語言了,工作中也是拿 Go 寫 infra
B16 青菜蘿蔔各有喜好了哦:) C++的確功能很多。工作上如果已經有C++環境,或許繼續用C++也是不錯的選擇。Rust的FFI讓你可以從C++ calls Rust,基本上跟call C是一樣的,所以基本上是可以混來混去。 Go拿來寫backend的優缺點,在B13我大概總結了一下。我自己也是Golang愛好者,只是在工作上用了幾年後,發現在某些時候有點侷限。不過絕大多數的使用情境都是ok的。
B18
Rust語言教學整本都是線上的哦。
靜宜大學
我比較期待julia,只是不知道為什麼台灣沒甚麼人在討論就是了
B20 我記得第一次看到Julia是因為在搜尋跟Numpy相關的資源。我猜可能目前大家對它的印象還停留在專做數值分析之類的吧?既然已經有熟悉的Python,可能就比較不會想嘗試另一個。單純是我自己的猜想哈哈。
靜宜大學 財務與計算數學系
B21 你說的這個沒錯,只是julia使用起來很像python+R,然後還有那個混合型別,使用起來速度可以媲美C,而且使用迴圈不容易造成效能損失。 只是任何一門程式語言最重要的還是它的生態圈,julia就可惜在這裡
國立臺灣大學 資訊工程學系
Dcard後端貌似使用Node.js和Golang,覺得這個stack滿潮的
B23 後端使用兩個通用語言啊?蠻有趣的。不知道為什麼這樣設計哈哈。
匿名
此帳號疑似異常
官方正在進行身份確認
B24 系統變大 後端會改成微服務 我猜是部分服務改成golang寫 因為node.JS 不擅長大量運算 我猜是因為這樣所以有些改為Golang
B25 原來不是一開始就用microservices的架構啊。Make sense!謝謝你的回覆。
匿名
此帳號疑似異常
官方正在進行身份確認
B26 因為狄卡一開始只是一個課堂作品 使用者慢慢變成現在的人數 才需要改寫架構
朝陽科技大學 資訊管理系
不同的服務根據規模和程式效率,適當切割改寫也能增進整體效能
B28 是啊!也比較容易分開部署。不過,我覺得到底要如何切成不同microservices;什麼時候需要切等等,是一門很靠經驗的事。因為切成太多,光是network I/O就可以讓你的latency增加很多;切成太少,那乾脆別切了哈哈!
朝陽科技大學
這就是系統規劃師和架構師值錢的原因⋯⋯
國立交通大學
真的讚 希望能多點公司用
B31 謝謝!我自己覺得Rust蠻有趣的,希望有更多公司可以讓我玩它哈哈。