首頁>技術>

有時候舊東西比你想象的更有價值。

來自過去的技術來拯救未來。這就是《Rust》的創造者格雷頓·霍爾(Graydon Hoare)所說的他想要實現的目標。

這是Rust的關鍵特徵之一:使用學術界眾所周知但很少在當代程式語言中實現的技術。老舊、可靠、有時被遺忘的技術。但最重要的是,它執行得非常好。

這些技術主要用於一件事:安全。

你可能會認為軟體開發人員是這個星球上最具創新精神的人。然而,Rust與“快速行動,打破常規”的咒語正好相反。儘管如此,Rust開發人員幾乎可以保證學習他們以前從未聽說過的概念。

從一些開發人員使用代數資料型別進行系統程式設計的新奇性,到Rust自己的記憶體安全方法:每個開發人員都可以找到一些新的、非常有用的東西來學習。還有更多的理由愛上Rust。

無需垃圾收集,更安全的記憶體

每一種程式語言都面臨著一個挑戰,即以一種安全有效的方式管理計算機的記憶體。例如,Python有一個垃圾收集器,它會在程式執行時不斷查詢不再使用的記憶體並清理它。

在其他語言中,如C和c++,程式設計師必須顯式地分配和釋放記憶體。由於所有與記憶體相關的問題都在程式執行之前被清除,因此這種方法對於最佳化效能更好。

另一方面,記憶體是開發人員需要一直考慮的另一件事。這就是為什麼用C編寫程式比用Python要花更長的時間的原因之一,即使它在一天結束時做的事情是一樣的。

Rust採用另一種方式:在編譯時透過所有權系統分配記憶體。這是一種巧妙的技巧,可以確保清理未使用的資料,而不必強迫程式設計師一直考慮分配和釋放記憶體。

Rust使用舊的技術進行有效的記憶體管理

基本上,所有權是三個規則的集合:

fn main() { let a = vec![1, 2, 3]; let b = a; println!("a: {:?}", b); }

在第二行中,建立所有者為a的向量[1,2,3]。之後,b成為向量的所有者。因為在print語句中呼叫了正確的所有者,這個程式在執行時編譯並返回預期的結果:

a: [1, 2, 3]

另一方面,你可以嘗試呼叫vector和它之前的所有者a,就像這樣:

fn main() { let a = vec![1, 2, 3]; let b = a; println!("a: {:?}", b, a);}

相比之下,Python會在第二種情況下執行。它的垃圾收集器只會在最後一次呼叫它之後才丟棄,這對開發人員來說很好,但在記憶體空間方面就不太好了。

在C中,事情會稍微複雜一些:您必須為a分配記憶體空間,然後將其指向vector,然後為b分配更多的記憶體空間,將b指向a,最後在您完成時釋放a和b佔用的空間。

從這個意義上說,Rust到記憶體的方法是開發速度和效能之間的妥協。雖然它不像Python那麼容易編寫,但是一旦您理解了所有權的概念,它就不會像C那樣笨拙。

另一方面,效率是相當驚人的:例如,開發團隊Tilde在Rust中重寫了一些JavaHTTP片段後,設法減少了90%的記憶體使用。

誰說Rust不能吸引人?

靜態型別而不太難看

這幾乎是動態型別和靜態型別愛好者之間的一場宗教戰爭。雖然用具有動態型別的語言編寫軟體要容易得多,但程式碼可能很快變得難以維護。這就是為什麼Python程式碼比C程式碼更難維護的原因之一。

另一方面,必須宣告每個變數的型別C-style會非常煩人。如果你曾經嘗試在返回C浮點型別的函式中使用double,你就會明白我的意思。

Rust走了一條中間的路:它是一個靜態型別系統,但它只需要程式設計師指定頂級型別,如函式引數和常量。在函式體內部,允許使用python風格的型別推斷。

Rust的一個特別有用的特性是,它也沒有任何型別。這允許您在編譯時處理異常,從而保證程式在終端使用者中平穩執行。考慮這個例子,我們可以得到一個人的全名,不管他是否有中間名:

fn get_full_name(fname: &str, mname: Option<&str>, lname: &str) -> String { match mname { Some(n) => format!("{} {} {}", fname, n, lname), None => format!("{} {}", fname, lname), } }fn main() { println!("{}", get_full_name("Ronald", None, "McDonald")); println!("{}", get_full_name("Dwight", Some("P."), "Eisenhower"));}

雖然在其他語言中也有None的版本,但它以一種簡潔的方式展示了Rust的雄心:在保持程式碼儘可能持久和可維護性的同時,不讓編寫變得過於困難。

一種極好的系統程式設計方法

雖然Python是一種通用程式語言,但Rust像C一樣,是用於系統程式設計的。雖然Rust不是為終端使用者製作應用程式的理想語言,但它非常適合構建為其他軟體提供服務的軟體。

因此,效率是Rust的核心。最好的例子是零成本抽象,它解釋程式碼的同時將記憶體使用保持在最低限度。正如c++的發明者Bjarne Stroustrup所說:“不用的東西,不用付錢。”而且:你所使用的,你不能再更好的手動程式碼。”

例如,考慮在Python中把不超過1000的所有整數相加:

sum(range(1000))

這在每次程式碼執行時都要進行1000次迭代和新增—您可以想象這會使程式碼變慢多少。相比之下,在Rust方面考慮同樣的事情:

(0..1000).sum()

這個編譯成常數499500。實際上,記憶體使用量已經減少了1 / 1000。

雖然這些抽象在C語言中也存在,但是Rust大量地使用了它們——事實上,一個目標就是在語言中新增儘可能多的零成本抽象。在這個意義上,Rust有點像下一個級別的C。

C已經存在了40多年,Rust的目標也是如此。Rust非常強調向後相容,所以今天您仍然可以在Rust 1.0中執行程式碼。同樣地,如果您今天編寫Rust程式碼,您應該仍然能夠在二十年後執行它。Rust不會生鏽!

一個小而不可思議的社群

它強調安全性和可持續性,所有漂亮的細節都說明了這一點,也難怪Dropbox在《Rust》中重寫了許多核心結構。Rust的第一個大讚助商Mozilla在其中編寫了Firefox的重要部分。微軟認為C和c++對於關鍵任務軟體不再安全,並在Rust問題上投入了越來越多的資金。

不僅是大公司,對Rust的熱愛也影響到個人程式設計師。儘管到目前為止StackOverflow的調查物件中只有5%的人使用Rust,但這些開發人員對該語言非常有熱情。

這是有原因的。不僅語言規範和編譯器是經過深思熟慮的。有rustup安裝和管理工具鏈。還有Cargo,這是一個命令列工具,它隨Rust安裝而來,幫助管理依賴關係、執行測試和生成文件。

板條箱。使用者可以共享和發現庫和文件。在rs中記錄它們。有來自Clippy的編譯器lints和來自rustfmt的自動格式化。

除此之外,還有官方和非官方的聊天、看板、使用者論壇、StackOverflow問題和世界各地的會議。在一個把友善看得高於一切的社群裡,還有什麼更好的要求嗎?

缺點:在你會走路之前,你需要先跑

關於Rust的一個令人沮喪的事情是高昂的啟動成本。雖然在大多數語言中,你需要一到兩天的時間來學習,但這更像是一到兩週的“Rust”。

這是因為有許多其他語言沒有使用的新概念,而且在編譯時通常會有很多錯誤。您需要在第一天就處理所有異常,不能像在Python中那樣編寫一個臨時程式碼來執行並在以後新增異常。

此外,由於Rust仍然是相當新的,並不是所有您可能需要的庫都在那裡。除了官方文件和StackOverflow上的各種問題,也沒有那麼多的教程。

好訊息是,一旦你掌握了這些概念並編譯了你的程式,它就會像魔法一樣執行。另外,考慮到向後相容性,它應該在20年內仍然可以工作。

考慮到您的程式碼的可持續性,以及Rust是由許多大公司支援的事實,一到兩週的預先學習可能是值得的,儘管有缺點。

This type of Rust won’t make your ship sink.

底線是:無所畏懼地進行攻擊

Rust不僅僅是安全。但難以否認的是,它的許多核心概念旨在消除記憶體洩漏和其他安全問題。在一個軟體就是一切的時代,安全是必須的。

可能每一種即將到來的語言都有其發展空間:Go越來越多地填充Python和Java的空間,Julia在資料科學領域追逐Python,而Rust則在Python和c++的領域中成長。Rust的特別之處在於它令人難以置信的社群,它的創新特性,以及它被設計用於未來幾十年的事實。

還有很多工作要做,其中只有一小部分可以而且將會生鏽。今天的新語言有很大的機會堅持一段時間,即使其他語言也會在未來幾年出現。但如果我必須把名片放在一種語言上,Rust將是一個安全的賭注。

本文:http://jiagoushi.pro/node/1397

20
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Go實戰——golang中讀寫檔案的幾種方式