“
本文是對今天 Reddit 熱帖:何時會考慮使用 Cpp 而非 Rust(Considering C++ over Rust)[1]中精彩討論的總結。Reddit 上面討論非常激烈,本文只是一些精彩評論的摘錄,大家可以去原帖閱讀更多討論。
背景
一位同時使用過 Rust 和 Cpp 的開發者,他用 Rust 主要是實現 Web 服務器和命令行工具,而 Cpp 則用于游戲開發(虛幻引擎)和編寫虛幻引擎插件。
最近他的一個使用 Javascript 的朋友問他:“你為什么要用 Cpp,它很糟糕,Rust 解決了 Cpp 的所有問題”。
這是Rust社區一直在使用的主要口號之一。
公平地說,這并不是這位開發者開始使用Rust的原因之一,他選擇使用 Rust是因為 Rust 的包管理工具 Cargo;另外一個原因是Node的創始人在談論Deno(用Rust編寫的Node.js的繼任者)時說:“我再也不會在我的生命中開始一個新的C++項目了”。
另一方面,他多年來一直在使用Cpp,主要是與虛幻引擎密切配合,但他從未遇到過通常由 Rust 社區列出的問題。Cpp 有智能指針,我覺得現代 Cpp 解決了很多被認為是 Cpp 弱點的問題。這主要取決于你是什么樣的程序員,以及你在其中的經驗。
所以,他在 Reddit Rust 和 Cpp 頻道都發了同一個帖子,想了解大家何時會選擇使用 Cpp 而不是 Rust ?
Rust 頻道的評論
sird0rius:
我討厭 Cpp 變得如此復雜龐大。Cpp 是我20多年前學的第一門語言,我嘗試學習一些更現代的寫法,但由于一些只有多年經驗才能學到的語言陷阱,我仍然無法達到通過一些基本的 Cpp 面試的水平。或者通過閱讀比《戰爭與和平》還長的這個龐然大物。作為一個職業選擇,對我來說學習 Rust 更有意義,因為我在進入底層編程方面比追趕 Cpp 標準更具競爭力。我認為,在學習基本的現代 Cpp 所需的時間里,我可以掌握 Rust 以及其他幾種編程語言。每當我了解 Cpp 的新知識時,我都會想:“為什么在 Cpp 中做這個事情要比在 Rust 中復雜得多呢?(例如移動和復制語義)”。即使 Rust 沒有大熱,我仍然可以依靠我在短時間內學到的其他語言。
pr06lefs:
我曾經是一名 Cpp 開發者,有15年的經驗。我現在仍然在做一些 Cpp 的工作,但是我更喜歡 Rust。Cargo是一個很重要的原因,其他函數式語言的便利也是,比如 match(而不是switch),沒有異常,以及一切都是表達式而不是語句。另外一個問題是 Cpp 中錯誤信息的質量很差。我經常不得不滾動頁面很長時間才能找到錯誤的實際位置。錯誤信息并不總是越多越好。使用一個不錯的 Cpp 子集進行編碼是可以的,但并不是每個人對于什么是這個不錯的子集都有相同的理解。有些人總是會探索可能性的邊界,只為了提升自己的技能。當你在20萬行代碼中的某個地方遇到一個無法重現的核心轉儲,或者一個只在調試模式下工作而在發布模式下不工作的大型程序時,這真是令人沮喪。追蹤那個因為數組操作錯誤導致的偏移量問題或其他問題可能非常耗時。這是一類令人討厭的問題,在安全的Rust代碼中根本不會出現。這就為我們留下了更多時間來解決有趣且有生產力的問題。
TheReservedList:
與作者相同的開發背景:游戲開發,工作中使用Cpp;個人項目用的是Rust。
Cargo 是選擇 Rust 的一個重要的理由。
表達力是另一個問題。Cpp 只需要更好的人機交互,但進展不夠快。
對 Cpp 又愛又恨。Cpp 是一門很棒的現代語言,但卻有一些愚蠢(至今)的遺留決策。
Cpp 模板比 Rust 的泛型更強大嗎?是的。我只是不夠聰明來進行復雜的模板元編程,而且我認為超過1%的 Cpp 程序員也不會。
游戲中的隨機平臺對現代 Cpp 的支持很糟糕,使用的是老掉牙的編譯器。這并不完全是 Cpp 的錯,至少不完全是,我只是發泄一下。
Cpp 中編譯單元的心智負擔實在太大了。包含文件太愚蠢了,他們應該廢棄那種編譯模型。我嘗試使用模塊,但支持還不夠。
phazer99:
這是百分之百正確的。當你在團隊中工作時,你會真正欣賞到Rust 及其工具相對于 Cpp(以及其他語言)所提供的優勢。現在我在一個由所有Rust初學者組成的團隊中,他們正在處理一個相當龐大的代碼庫,但代碼仍然非常統一、易于理解和維護。Rust 編譯器(以及Clippy)真正強制/鼓勵每個人遵循良好的習慣和編碼風格。很少有 unsafe 代碼,因為每個人都知道涉足這個領域的“危險”。Cargo 還使處理內部和外部依賴變得輕而易舉。
sayhisam1:
就是這樣。Cpp 有選擇性的安全性,我發現在實踐中這真的很困難。有沒有一本簡短、易于記憶的“白癡安全Cpp”類型的書,我可以參考一下?即使有了這樣的書,我也要自己確保不會意外地寫出一些不安全的代碼。在Rust中,安全代碼是默認的;你必須明確地將其包裝在 unsafe 的代碼塊中,并且必須意識到這一點。在不安全的區域之外,我幾乎可以保證不會出現使用后釋放錯誤或類似的問題。Rust 的風格也更加一致,因為標準庫更加合理,教程也非常棒。
zoomy_kitten:
模板是90年代的一個支撐,旨在滿足開發者在普通靜態多態和普通元編程方面的需求。Rust 的泛型和宏是我選擇 Rust 而不是 Cpp 的原因之一。毫無疑問,模板是一個強大的工具,尤其是在當時。別誤會,我并不是要冒犯 Cpp,它是一門了不起的語言,如果沒有 Rust,我可能會更經常地使用它。但是與 Rust 提供的功能相比,如今它的特性相當可憐。Cpp 是一門靠支撐物生存的語言,而 Rust 是一門擁有健康雙腿的語言。
Orthosz:
Cpp 已經存在了大約 40 年。其他具有“現代”方式但保留了類似時間的舊東西的語言也有大量糟糕的教程。我敢打賭,在未來的30年里,Rust 會有糟糕的教程,教授一種混合了舊方式、新近方式和新方式的內容,因為 Rust,就像 Cpp、Java和其他系統語言一樣,承諾向后兼容。
TheReservedList>Orthosz:
永恒的向后兼容性,就像 Cpp 那樣,從長遠來看永遠行不通,每一種語言都注定會失敗。起初我以為這就是版本的意義,但似乎對于這樣一門年輕的語言來說,改變已經存在很多猶豫。
Orthosz:
這將讓每個人都感到不舒服,而且應該如此:constexpr、模板元編程和預處理器宏讓你以一種弗蘭肯斯坦怪物的方式做出真正令人驚嘆和可怕的事情。
harmic:
另一個關鍵因素:在許多情況下,C++編譯器的錯誤信息非常糟糕。想象一下,從你錯誤使用的某個模板庫深處涌出一大堆無意義的內容。Rust編譯器的錯誤信息通常非常出色,甚至經常提供修復問題的建議。
dkopgerpgdolfg:
不,Rust并不能解決所有問題。我猜寫一部分現代C++代碼可能會很不錯。但這并不是我來到Rust營地的主要原因。相反,最迫切的原因是因為"Cpp"并不等同于"現代Cpp的子集"。如果我能“寫”出漂亮的Cpp,但人們仍然能夠寫出280頁的書來解釋變量初始化,那對我有什么幫助呢?代碼也需要被“閱讀”。包括那些不符合個人偏好的代碼。Cpp確實非常有用。但它也變得非常復雜,有時候我不明白為什么我要繼續朝這個方向發展——越來越多的時間花在查找標準、缺陷報告等符號上,而不是編寫有用的代碼。Rust 也不完全擺脫這個問題,但兩者之間有天壤之別。
KnorrFG:
在Rust出現之前,C++曾經是我首選的編程語言。不過現在我不再使用它了,除非是在嵌入式領域。我從來沒有在內存管理方面遇到太多困難,但項目配置和依賴關系真是讓人煩惱。我使用過makefiles、scons、cmake和Visual Studio,它們各有各的煩人之處。尤其是與Cargo相比。總的來說,使用包含方式處理多個文件是一種糟糕的方法。我仍然記得花了兩天時間搜索一個錯誤,因為一個頭文件中的定義覆蓋了一個無關依賴項中的函數。我真的很煩迭代器的管理。到處都是.begin()和.end()...太丑陋而啰嗦了。哦,還有模板錯誤...然后在Rust中有一些非常吸引人的東西:代數數據類型、問號運算符、Cargo以及大部分自動類型推斷。單獨來看,這些都不算什么,但是所有因素的結合使得 Rust 對我來說顯然更具吸引力。
adwhit2:
我不明白為什么有人經歷過帶有和類型的語言后,還會愿意回到沒有和類型的語言。這就像是用一只手綁在背后進行編碼。
C++現在有std::variant了,但是在人機交互方面,它與Rust的枚舉和模式匹配相比還有很大差距。
std::visit是match的一個糟糕的替代品。最具體地說,在一個match的情況下,我可以continue/break/return,因為這個match與match處于相同的函數上下文中...然而,在std::visit中的lambda函數中,我不能...因此,我需要將continue/break/return重新定義為一個結果值(或標志),然后在std::visit之后根據它進行分支。當人們贊揚某種類型時,他們實際上贊揚的是模式匹配 :)
safdwark4729:
Rust目前缺乏特化和反向類型 trait,可以說這是Rust與Cpp不同的一個差距,類似于和許多其他Rust特性一樣。當然,我仍然認為實際的泛型是比模板更好的選擇,只是恰好這些特性對于高性能代碼和甚至安全性(單位……你現在在Rust中很難做到這一點,也有其他原因)非常重要,并且在庫生態系統和常量泛型之后,它們是阻止我在Rust中做更多事情的最大問題之一。
忽略自身不斷完善的庫生態系統,Rust 需要(或等效功能/或使其變得無關):
Specialization 特化
Negative Type traits 反向類型 trait
Static assert靜態斷言
Placement New
用戶自定義字面量
據我所知,所有這些都正在進行中/將來的工作計劃中,但其中一些我現在需要,就像現在這樣,并且與Rust的愿景相一致。
randompittuser:
我已經使用C++二十年了,Rust使用了一年。我可能會因為我的觀點而遭受r/rust的憤怒,但是我還是要說:對于有經驗的 Cpp 開發者來說,Rust并沒有太多吸引力,但并非每個人都是有經驗的 Cpp 開發者。Rust 的最大優勢之一是將許多運行時/內存錯誤轉移到編譯時。為了實現這一點,與 Cpp 相比,它對類型及其使用的假設進行了限制,使得 Rust 更冗長(盡管可能更具表達力),尤其是在高級用例中。然而,請考慮到 Rust 相對于 Cpp 還處于起步階段,我相信在未來十年內,它有潛力超越 Cpp,在新項目中得到更廣泛的應用。考慮到這一切,我會說學習兩者都是不錯的選擇。
Cpp 頻道的評論
msqrt:
我曾經簡單嘗試過 Rust。確實,知道編譯器可以在很多錯誤發生之前就捕捉到它們,這讓人感到非常放心。但就個人而言,這并不足以讓我放棄我已經相當熟悉的語言,轉而去學習一門需要付出相當努力的新語言。我覺得C++在不久的將來可能會失去很多地位,但我并不急于成為這個過程中的早期采用者。我會先看看情況如何發展。
Sudden_Job7673:
C++面臨的一個重大挑戰是,在互聯網時代之后,它的發展機制無法像其他生態系統那樣快速改進。缺乏一個能夠在編譯時檢測到可能導致錯誤的機制,對于什么是C++的慣用方式缺乏共識(是否包括異常處理?),缺乏一個被廣泛采用的不穩定C++版本來嘗試新的理念,以及二進制穩定性使得一旦某個特性進入標準后很難進行修正。
jgaa_from_north:
變化的速度和范圍是我現在更加關注 Rust 的原因之一。這是我暑假的“項目”。當C++發生變化時,你被認為應該理解新的方式和舊的方式。你需要了解的內容總量在這個已經相當復雜的語言中以很高的速度增加。我并不羨慕那些今天學習C++的人。
此外,這些變化并未解決C++中一些最緊迫的問題,比如缺乏標準的構建系統、標準的軟件包管理器或倉庫基礎設施。當一個項目不斷發展時,管理常常沖突的遞歸依賴關系是一種痛苦。自1996年以來,我一直將C++作為我的主要編程語言。我可能已經寫了超過一百萬行的C++代碼。我仍然比我使用過的任何其他編程語言更喜歡C++。我的觀點是,標準中的變化/創新是一把雙刃劍。
guyinnoho:
Rust 是較新的。再給它十年,然后再比較。
dzordan33:
在 Rust 生態系統中,低門檻是一個巨大的優勢。在我看來,雇傭那些能夠并愿意學習 Rust 的聰明程序員要比經驗豐富的 C++ 開發者更容易。根據我的經驗,你不必是一個 Rust 專家才能高效工作。
darth_chewbacca:
你好,我來自這個討論主題的 Rust 版塊。請不要惡意攻擊。我曾經是一名 C++ 開發者,最后接觸的版本是 C++17。我最喜歡的語言是 Rust,但我仍然喜歡 C++。
對于一個熟悉“現代C++”并且是資深C++開發人員來說,學習Rust并不太困難。在之前的雇主那里,我幫助培訓了幾位C++開發人員(還有一位經驗豐富的Java開發人員),他們學習起來并不困難。但是C開發人員、C#開發人員以及Python/JavaScript開發人員確實遇到了一些困難。
C++和Rust比大多數其他廣泛使用的編程語言更相似。現代C++在用法上可能比原始的C更接近Rust。對你來說,學習曲線可能沒有其他嘗試Rust的人那么陡峭。
當你聽到關于Rust學習曲線的抱怨時,這些抱怨通常不是來自以前的C++開發者。
nihilistic_ant:
很長一段時間里,Java一度被認為會取代C++。Sun公司用Java編寫了一個操作系統,而Netscape則將他們的瀏覽器移植到了Java上。后來,我記得有一段時間Go語言被認為會取代C++,但回想起來,這種說法并沒有多大意義,盡管當時看起來似乎很有道理。除了這些大型語言之外,還有很多其他流行的語言,人們常常問為什么項目選擇使用C++而不是它們,盡管它們當時很熱門,比如D語言或者Scala,雖然現在它們已經被人們遺忘,但在一段時間內它們占據了很多人的關注。
也許Rust會真的做到。也許Zig會。也許幾年后會有一些東西開始。很難說。
總的來說,我不羨慕那些總是追逐最新編程語言和框架的程序員。(幾年前對他們來說尤其艱難,因為他們不得不在短短幾年內學習了大約6個JavaScript框架,以跟上潮流。)他們的代碼最終變得難以維護,因為會有各種用不再流行的語言或框架編寫的系統存在。
無論如何,如果Rust或Zig真的能夠主宰世界,我會很高興轉向它們。但對我個人來說,等待幾年看看是否真的如此是有道理的。
像Rust這樣的新語言的一個問題是,它們的用戶都是決定使用最新、最酷的語言的程序員。這意味著,如果有什么新東西出現,他們的用戶很可能會轉投他。而那些仍然使用C++進行編程的人在很多次之前都選擇了不轉投其他語言,所以我相信這門語言至少會在相當長的時間內相當受歡迎。
laralex:
我對C++的三大痛點是:
每個角落都潛伏著大量無聲的UB(未定義行為),即使對于經驗豐富的程序員來說,也很難記住它們
庫管理不足
混亂的標準庫以非常丑陋的方式包裝了舊錯誤(但仍保持向后兼容)然而,我覺得僅僅淘汰C++還不夠,因為在大型科技公司中,選擇C++是一個顯而易見的選擇,這也是在職業生涯中提升的難題,沒有掌握C++是很難有進展的。Rust仍然被視為一只昂貴的獨角獸,轉向它可能代價過高。
monsoon_winds:
哥們兒,現代C++可以避免老版本C++的問題,但只要向后兼容性存在,老版本C++仍然存在。在編寫C++代碼時,你需要一直積極地避免這些問題,直到你的生命結束。而Rust則默認提供了你所需要的,你需要主動選擇進入不安全模式,才會出現問題。
把自己(或任何有經驗的程序員)看作是一個無法寫出任何錯誤的編程之神,這種想法實在是愚蠢的。我會在這里鏈接到cpp2的演講[2],Herb在其中用簡單的話解釋了這個問題。
正如你所提到的,shared_ptr和一些現代特性確實有所幫助,但它仍然只是對這個巨大的UB潛在問題的臨時解決辦法。即使是像Cherno(著名的YouTuber)這樣經驗豐富的游戲引擎開發者,也不得不花費數小時進行調試,最終才發現在一個for-each循環中,他們無效化了迭代器 :D
你對“有經驗的程序員”的定義也不具體可行。如果谷歌/微軟這樣擁有龐大預算的公司都無法保持軟件質量,那么其他隨機公司又有什么機會呢?
tiajuanat:
請記住,我是一個有7年最近活躍的C++編程經驗的新手,但我幾乎一生都在以某種方式進行編程。
我有些猶豫,但不得不說Rust自帶了許多很棒的功能,而C++在這方面還遠遠無法媲美。Conan、CMake、Doxygen、Catch/Doctest/GTest,Rust都有自己的系統來處理這些,而且還有更多其他功能。
有一些地方是痛苦的。所有權并不總是一帆風順的,在與其他C++開發人員合作編寫Rust代碼時,會出現“正確方式”和“Rust方式”的爭論。上個月,我與人合作開發串行協議時,弄清楚哪個系統“擁有”串行端口并不容易,最后使用了一個奇怪的弱指針。
Rust有一些不完美的地方嗎?絕對有。事實上,我認為沒有這些不完美的地方,你就無法擁有一種適用于工業系統的編程語言。然而,我很少感覺到與Rust 的斗爭,而且我已經積極地使用 Rust 幾個月了;而在C++中,我花了七年的時間才達到這個水平。
本文結語
你不能只是把一本 Rust書放在開發人員手上,希望通過知識滲透讓他們學習到 Rust 所有權。
-
C++
+關注
關注
22文章
2114瀏覽量
73839 -
編譯器
+關注
關注
1文章
1642瀏覽量
49270 -
cpp
+關注
關注
0文章
10瀏覽量
2128 -
Rust
+關注
關注
1文章
230瀏覽量
6658
原文標題:Reddit 觀察:你何時會考慮使用 Cpp 而非 Rust ?
文章出處:【微信號:Rust語言中文社區,微信公眾號:Rust語言中文社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論