當前位置:
首頁 > 科技 > Rust 編程有什麼好?

Rust 編程有什麼好?

Rust是一種現代系統級編程語言,在設計時考慮了安全性,此外,它提供零成本抽象、泛型、功能特性等等。但是通常對於開發者來說,Rust上手門檻較難,而它究竟難在了哪裡?此外,它還具備哪些優勢以及缺點?接下來,本文將從語言、工具、庫等多個角度一一探索Rust中的奧秘。

作者 | Brenden Matthews

譯者 | 姜松浩

責編 | 屠敏

出品 |CSDN(ID:CSDNNews)

以下為譯文:

這篇文章是關於我通過解決Twitch上的每個CtCI問題來學習Rust的經驗(https://github.com/brndnmtthws/cracking-the-coding-interview-rust),這是一個未完成的項目。

最近,我開始努力學習Rust,在此我想分享一些心得體會。

近日,我在Rust中編寫了一些小程序,並且在閱讀了一半的「Programming Rust」書籍之後發現,我是真的不了解Rust。基於此,我想出一個很好的方法來了解這門語言,那就是嘗試去解決「Cracking the Coding Interview」一書中的所有189個問題。我不僅會用Rust解決它們,而且還決定在Twitch上直播。對於提供技術講座,或者在觀眾面前編碼,我並不陌生,但嘗試學習一種編程語言,並解釋我所做的——讓全世界都看到——對我來說是一種新鮮的東西。

事情開始有點不順利:技術問題、流問題、工具問題,而且我一開始很難理解內存範式。我試著這樣做,同時也對人們解釋我做了什麼,這是個…棘手的問題。

我花了大約8個小時來實現一個鏈接列表:我記錄了的兩個4小時的流,試圖弄清楚如何正確使用Rc,RefCell和Box。有一段時間我覺得我只是在敲擊鍵盤嘗試隨機組合,直到出現問題。令人驚奇的是,人們都在觀看。我一定是做對了。

離線看書一段時間後(按照一本非常有用的書「Learning Rust With Entirely Too Many Linked Lists」),我開始理解了這些概念。完成我的鏈接鏈表實現後,事情變得容易了許多。

我現在已經讀到了那本書的第4章,我覺得我已經邁出了Rust的第一步。Rust一旦編譯起來就會讓人感覺自然、高效,並且非常令人滿意。Rust是強類型的,並提供優秀的編譯器消息:如果你學會了使用編譯器,除非代碼存在邏輯缺陷否則你的代碼就能得以運行。

Rust的一個可愛特性是編譯器有很大的幫助。例如,C 代碼的編譯器消息非常難以理解。雖然Clang已經在其錯誤消息方面取得了巨大進步,但Rust的編譯器則是另一個更有幫助的工具。

我將總結一些我到目前為止的發現。這是基於我最初的反應,我承認我對Rust的專業知識很匱乏,但是對於其他人來說,看看他們的學習經歷與我的相比較,可能仍然會覺得很有趣。我遺憾地承認我沒有徹底研究下面的每個問題,所以我可能有過時的或不準確的信息。

語言:好的方面

首先,感謝Rust團隊以及為項目做出貢獻的每個人。這是我有史以來我所擁有的最有趣的編程語言學習經歷之一。我不知道Rust是否會像其他一些語言一樣吸引開發人員的注意力,但我認為它將繼續存在。詳細情況如下:

Rust代碼相當容易閱讀,並且不會受到諸如C 、Scala之類的語言難以解析的語法的影響。它似乎擁有我所期望的功能,而挑戰僅僅在於確定調用哪個函數。

像具有map(),filter(),find()等功能特性是一種樂趣。定義高階函數並將閉包傳遞給它們是輕而易舉的。它不會像Ruby這樣的語言一樣很容易的進行函數式的編程,但它卻很接近。事實上,對於一種與C / C 相當的語言而言,它是那麼容易實現,這多麼令人興奮。

Rust會強迫你仔細思考內存分配,因為你別無選擇。到最後,這就意味著混亂的代碼難以編寫,而良好的代碼卻很容易編寫。這些抽象也會直接映射到編寫安全的並發代碼。

Rust的零成本抽象的方式,會使得不會增加開銷的情況下編寫好的代碼變得容易。這樣的特性提供了沒有性能損失的現代編程抽象。

Rust代碼是安全的(前提是你不使用unsafe關鍵字,或者調用不安全的C庫)

Rust的Result和Option提供了一種通過返回可能值或可能包含值的變數的函數處理的好方法。 而C,C 甚至Java中的常見模式是函數在沒有任何返回時返回空指針。在大多數情況下,當這種返回空指針的處理方式的發生意外情況時,會導致一些函數遇到麻煩。

語言:壞的方面

我發現有時需要unwrap(),as_ref()和borrow()這些有點冗長。我希望有一些語法糖來減少我必須以不同模式將這些調用鏈接在一起的次數。我發現自己經常編寫類似於tooption.as_ref().unwrap().borrow()的代碼,這讓我感覺很煩。

為了能夠在合理的時間內編譯代碼,編譯器需要做一些權衡。因此,在某些情況下,rustc無法推斷類型,或者需要一些人工幫助才能編譯代碼。對我來說,我發現有時很難弄清楚編譯器需要什麼,以及為什麼它不能為我弄清楚。

有些事情偶爾會覺得過於冗長。例如,在str和String之間進行轉換,或者將引用而不是值傳遞給函數,這似乎是編譯器可以為我解決的事情。我確信這會有一個很好的理由解釋為什麼它是這樣的,但偶爾也會感覺rustc太正確了。

需要處理每個函數的每個結果都很是好的;這意味著程序員必須考慮每個函數調用發生了什麼。有時候感覺很乏味。運算符?可以減少一些冗長,但是沒有很好的通用方法來處理故障類型。創造像failure和error-chain這樣會使處理故障更容易,但是你仍然需要為可能發生的每種類型的錯誤明確定義一個案例。

語言:丑的方面

宏:wtf?與其他語言相比,Rust宏感覺就像是左轉彎。公平地說,我還沒能深入理解它們,但是它們感覺不太合適,就像某種奇怪的栓接附件,這種附件是在語言被設計出來之後受到Perl的啟發才出現的。我最終會花一些時間來理解它們,但現在我想避免它們。就像躲避瘟疫一樣。

工具:好的方面

Rust提供了不錯的工具,並進行了IDE集成就像VSCode集成了RLS。 RLS支持動態鏈接、代碼完成、語法檢查和格式設置。

Cargo是Rust強大的包管理器:如果你嘗試過Rust,你將會對它非常的熟悉。在大多數情況下,能夠用Cargo進行工作是一個愉快的事。已經有大量的Cargo插件提供了像代碼覆蓋這樣的附加功能。

Cargo也是一個構建系統,它可用於運行單元和集成測試。配置你的構建和依賴關係是一個簡單的過程,因為它有一些聲明性的TOML 語法。

Cargo與crates.io進行了集成,crates.io是開源Rust項目的權威來源。就像PyPi或RubyGems一樣,你會發現幾乎所有其他的Rust包都託管在crates.io上。

rustup是管理Rust安裝的首選工具。你可以選擇穩定版、測試版或夜間頻道,並安裝所有先前版本的特定版本。它還允許你安裝clippy和rustfmt等組件。

如果你是像我這樣的完美主義者,那麼clippy是一個必不可少的工具。它將幫助你學習Rust解決問題方法,它可以捕獲許多你可能不會注意到的常見錯誤。對我來說,當我知道解決問題的方法時,但我不知道正確的方法的時候,clippy很有幫助,。

rustfmt是Rust的固定代碼格式的程序。在我看來,固定的格式才是最好的方式。當一切都遵循相同的標準時,就沒有了關於代碼格式的爭論。

sccache是一個編譯器緩存,它可以通過減少編譯時間來加快速度。但是-請注意-sccache不能與RLS一起使用,所以你無法在IDE中使用它。

工具:壞的方面

好了,在我繼續討論Rust的問題之前,我們都應該承認這是一項正在推進中的工作。 雖然Rust工具已經發展得很快了,但我認為還有很長的路要走。下面我將重點介紹一些需要改進的事項:

編譯感覺很慢。它不僅速度慢,而且我發現我經常需要重新編譯包。我理解這種必要性,但有時仍然很煩人。 sccache雖然有一定幫助,但編譯仍然感覺很慢。有一些方法可以緩解這種情況,例如使用cargo check 來取代cargo build。

RLS使用Racer完成代碼,我發現它最多只能命中或錯過(至少在VScode中是這樣的)。我希望完成的函數通常不存在,不存在的函數顯示為完成選項。我沒有做徹底的分析,但這些建議似乎只有75%的時間是正確的。造成這種情況的原因可能僅僅是由於RLS的緩慢。

No REPL:這可能不公平,因為C 都沒有像樣的REPL,但是現在很多語言都帶有REPL。關於這一點,GitHub上有一個未解決的問題。一個好的REPL不是必需的,但會有所幫助。

工具:丑的方面

RLS緩慢,很厚重還有經常崩潰。對我來說,至少,我發現我經常需要在VSCode中重啟RLS。 RLS是一個很棒的工具,但它確實讓人覺得感覺它充其量只是一個測試版本。我發現自己不得不停下來並且等待RLS趕上來,這樣我可以確保我沒有編寫錯誤的代碼。有時我認為最好簡單地禁用RLS,編寫代碼,然後嘗試編譯它,就像過去我在Vim中完成所有編碼一樣。基本上RLS就像變成了一個多餘的拐杖,更多的是分心。

庫:好的方面

Rust生態系統中出現了大量可用的庫。似乎有一個熱潮要衝出去實現所有Rust的庫,並讓你的名字在Rust歷史中永存。你可以在crates.io或GitHub上找到你所期望的大部分內容。我常常驚訝於每次搜索都會出現2或3種不同的實現。

我使用的大多數庫能夠按預期工作,許多庫甚至超出了預期。這些庫是與替代方案,也就是那些不起作用的庫的細微而重要的區別。

庫:壞的方面

雖然沒有Node.js生態系統那麼糟糕,但每個庫的依賴關係列表已經變得很長。我寫了一個名為LabHub的小型GitHub機器人,我仍然對有多少依賴項感到驚訝(如果你想知道的話,可以有181個)。對我來說,這表明碎片和重複,這可以通過將一些廣泛需要的功能慢慢地

庫:丑的方面

我注意到,除了一個相對簡單的應用程序的依賴項列表外,我還多次編譯相同庫的不同版本。我認為Cargo為了保持向後兼容性試正圖變得聰明;它正在根據語義版本來猜測應該包含哪些庫。令我擔心的是,當你擁有一個依賴於某個其他庫的古老的、破損的版本的庫,同時這個庫還有漏洞,這時會發生什麼。我毫不懷疑Rust的作者已經考慮過這些問題了,但它仍然看起來很奇怪。公平地說,處理依賴項間的依賴關係是一個非常棘手的問題。值得慶幸的是,有一個Cargo的樹工具可以幫助對這些東西進行排序,然後你可以強制一個依賴來升級它的依賴項。

最後的想法

Rust是一門很棒的語言。如果編程是你熱衷的事情,那麼就請試一試吧。我希望你能夠喜歡它。

原文:https://hackernoon.com/programming-in-rust-the-good-the-bad-the-ugly-d06f8d8b773

本文為 CSDN 翻譯,如需轉載,請註明來源出處。作者獨立觀點,不代表 CSDN 立場。

熱 文推 薦


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CSDN 的精彩文章:

為什麼都敏捷開發了項目還會延期?!| 技術頭條
Google 要進軍遊戲行業了?!

TAG:CSDN |