欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
一文解決現代編程語(yǔ)言選擇困難:命令式編程

本文轉載自 InfoQ,作者:Ilya Suzdalnitski 翻譯:蓋磊

如何了解某種編程語(yǔ)言的優(yōu)缺點(diǎn)?某種編程語(yǔ)言是否適用于我的項目?面對此類(lèi)問(wèn)題,如果求助于搜索引擎,輸入“最佳編程語(yǔ)言”,結果會(huì )羅列一堆文章,涵蓋 Python、Java、JavaScript、C#、C++、PHP 等,并且大多對各語(yǔ)言的優(yōu)缺點(diǎn)表述得模棱兩可。我本人很不喜歡去讀此類(lèi)文章,因為其中許多部分內容的表述并不到位,缺少實(shí)戰借鑒意義,而且行文生硬。因此我試撰本文來(lái)做一次深入總結,去偽存真。

本文概述了當前廣為使用乃至可能小眾的現代編程語(yǔ)言,力圖做到盡量客觀(guān)、值得一讀,并不帶個(gè)人偏見(jiàn)。各語(yǔ)言按推薦程度從低到高依次列出。

謹記,并不存在所謂完美的編程語(yǔ)言。有的語(yǔ)言非常適用于后端 /API 開(kāi)發(fā),而有的語(yǔ)言則非常適用于系統編程。

文中按當今兩大通用語(yǔ)言家族分類(lèi),即 C 衍生語(yǔ)言家族和元語(yǔ)言(Meta Language,ML)衍生語(yǔ)言家族。

對于開(kāi)發(fā)人員而言,編程語(yǔ)言只是工具箱中的工具,更重要的是如何選擇合適的工具去完成工作。我衷心希望本文有助于讀者選取適合自身項目的編程語(yǔ)言。做出正確的選擇,可降低數月甚至數年的開(kāi)發(fā)工作量。

哪些編程語(yǔ)言特性值得關(guān)注?

很多編程語(yǔ)言排行榜文章,主要對比的是語(yǔ)言使用廣泛度、開(kāi)發(fā)人員收入期望值等因素。在軟件領(lǐng)域,雖然大規模的社區和生態(tài)系統的確有所裨益,但語(yǔ)言的使用情況并非好的排行指標。本文另辟蹊徑,采用的評判依據主要考慮語(yǔ)言的強大之處和不足之處。

為表示所列語(yǔ)言的推薦程度,文中使用“贊”(??)、“否”(??)和“尚可”(??,即不贊也不否)三種 emoji。

那么應該比較哪些特性?換句話(huà)說(shuō),除了語(yǔ)言使用廣泛性,還有哪些特性更能代表語(yǔ)言的受歡迎程度?

類(lèi)型系統(Type System)

類(lèi)型系統倍受大量開(kāi)發(fā)人員的青睞,這也是為什么 TypeScript 之類(lèi)的語(yǔ)言日漸大行其道。在我看來(lái),類(lèi)型系統去除了大量的程序錯誤,更容易實(shí)現重構。但是否具有類(lèi)型系統,只是本文考慮的部分評判因素。

支持類(lèi)型系統的編程語(yǔ)言,最好同時(shí)具備類(lèi)型推斷(type inference)。一個(gè)好的類(lèi)型系統,不用明確地標出函數簽名(function signature),也能支持對大部分類(lèi)型的推斷。不幸的是,大多數編程語(yǔ)言提供的僅是基本的類(lèi)型推斷功能。

更進(jìn)一步,支持代數數據類(lèi)型(Algebraic Data Types,ADT)的類(lèi)型系統評分更高。

強大的類(lèi)型系統,還應支持高級類(lèi)類(lèi)型(higher-kinded types)。高級類(lèi)類(lèi)型是對泛型(generics)的更高階抽象,支持編程人員在更高的抽象層上編程。

盡管大家對類(lèi)型系統寄予厚望,但還有一些比靜態(tài)類(lèi)型(static typing)更重要的特性。因此在選擇一門(mén)編程語(yǔ)言時(shí),不能只看是否支持類(lèi)型系統,

學(xué)習難度

即便編程語(yǔ)言是完美無(wú)瑕的,如果一位新手上船需要前期投入數月甚至是數年的精力,那么又會(huì )有多少人使用呢?另一方面,很多編程范式需要數年的時(shí)間才能逐漸完善。

好的編程語(yǔ)言需對新手友好,掌握它們不應花費大量學(xué)習時(shí)間。

空值

我將 1965 年創(chuàng )建的空值引用(null reference)稱(chēng)為“億萬(wàn)美元錯誤”。當時(shí),我正設計首個(gè)完全類(lèi)型系統,用于面向對象語(yǔ)言中的引用。目標是確保所有對引用的使用是絕對安全的,并由編譯器自動(dòng)執行檢查。我無(wú)法克制添加空值引用的誘惑,完全因為空值引用非常易于實(shí)現。近四十年來(lái),這一設計導致了不計其數的錯誤、漏洞和系統崩潰,可能造成了數十億美元的痛心損失。

— 空值引用的創(chuàng )立者 Tony Hoare

為什么說(shuō)空值引用是不好的?因為空值引用破壞了類(lèi)型系統。一旦默認為空值,那么就不能依靠編譯器檢查代碼的有效性。任何空值都是一枚隨時(shí)可能引爆的炸彈。如果沒(méi)能想到所使用的值的確為空值,那么會(huì )產(chǎn)生什么后果?會(huì )出現運行時(shí)錯誤。

function capitalize(string) { return string.charAt(0).toUpperCase() + string.slice(1);}capitalize('john'); // -> 'John'capitalize(null); // 未捕獲類(lèi)型錯誤:不能讀取為空值的屬性“charAt”。

為確保所處理的值并非空值,開(kāi)發(fā)人員必須對運行時(shí)做手工檢查。即使是靜態(tài)類(lèi)型語(yǔ)言,空值引用也破壞了類(lèi)型系統的很多優(yōu)點(diǎn)。

function capitalize(string) { if (string == null) throw 'string is required';return string.charAt(0).toUpperCase() + string.slice(1);}

運行時(shí)檢查也稱(chēng)為“空值防護”(null guards),在現實(shí)中可歸為一種不良的編程語(yǔ)言設計。一方面,引入樣板代碼破壞了編程風(fēng)格。更糟的是,它并不能確保我們是否檢查了空值。

好的編程語(yǔ)言,應在編譯時(shí)做類(lèi)型檢查,判斷值的存在與否。

因此,支持空值檢查機制的編程語(yǔ)言應加分。

錯誤處理

捕獲異常并不是一種好的錯誤處理方式。拋出異常本身沒(méi)有問(wèn)題,但僅適用于程序沒(méi)有辦法恢復而必須崩潰這類(lèi)異常情況。異常和空值一樣,會(huì )破壞類(lèi)型系統。

如果將異常作為錯誤處理的首選方式,那么就無(wú)法獲知函數是返回了期望值,還是發(fā)生了故障。拋出異常的函數也無(wú)法實(shí)現復合(Compose)。

function fetchAllComments(userId) { const user = fetchUser(userId); // 可能拋出異常。const posts = fetchPosts(user); // 可能拋出異常return posts // posts 可能為空值,這會(huì )再次導致異常。.map(post => post.comments) .flat();}

無(wú)法獲取部分數據而導致整個(gè)程序崩潰,這顯然并非一種好的做法。盡管我們不希望發(fā)生這種情況,但它的確會(huì )發(fā)生。

一種做法是手工檢查是否生成異常,但是在編程過(guò)程中可能會(huì )忘記對異常做檢查,因此這種做法是非常不可靠的,而且會(huì )在代碼中添加大量額外處理。

function fetchAllComments(userId) {  try {    const user = fetchUser(userId);
    const posts = fetchPosts(user);
  1. return posts
.map(post => post.comments) .flat(); } catch { return []; }

目前已有更好的錯誤處理機制,支持在編譯時(shí)對潛在錯誤做類(lèi)型檢查。因此,默認無(wú)需采用異常處理的編程語(yǔ)言也應加分。

并發(fā)

當前業(yè)界正處于摩爾定律的末端,即處理器不會(huì )再大規模提速。我們身處多核 CPU 時(shí)代,所有的現代應用必須能很好地利用多核技術(shù)。

不幸的是,大多數當前在用的編程語(yǔ)言都是設計用于單核計算時(shí)代的,本質(zhì)上并不能有效地支持多核處理。

一種亡羊補牢的設計,是在后期提供支持并發(fā)的軟件庫。但這只是給語(yǔ)言打了補丁,并非從根本上就針對并發(fā)設計,不能稱(chēng)為良好的開(kāi)發(fā)體驗。一些現代語(yǔ)言?xún)冉藢Σl(fā)的支持,例如 Go、Erlang 和 Elixir 等。

不可變性

我認為大型的面向對象程序,需要解決由于大規??勺儗ο箝g關(guān)聯(lián)所導致的復雜圖結構。否則在調用方法時(shí),必須得把握并牢記該方法的功能和副作用。

—— Rich Hickey,Clojure 創(chuàng )建者。

當前的編程工作中,使用不可變值越來(lái)越常見(jiàn)。即便是 React 這樣的現代 UI 軟件庫,也考慮使用不可變值。對支持不可變數值提供一等支持的編程語(yǔ)言,我們會(huì )給出更高的評判。這完全是因為不可變性避免了編程中出現許多軟件缺陷。

什么是不可變狀態(tài)?簡(jiǎn)而言之,就是數據不會(huì )發(fā)生改變。例如,大多數編程語(yǔ)言中的字符串。字符串轉為大寫(xiě),并不會(huì )去改變原始的字符串,而是返回一個(gè)新的字符串。

為確保任何事情都不發(fā)生改變,不可變性對上述理念做了進(jìn)一步擴展。更改不可變數組,總是會(huì )返回一個(gè)新的數組,而非原始數組。更新用戶(hù)名,將返回一個(gè)包含更新后用戶(hù)名的新用戶(hù)對象,并不改變原始對象。

不可變狀態(tài)不做任何共享,因此無(wú)需操心線(xiàn)程安全所導致的復雜性。不可變性使得代碼更易于并行化。

不對狀態(tài)做任何更改的函數,稱(chēng)為“純函數”(Pure)。純函數更易于測試和推斷。使用純函數,無(wú)需操心函數體之外事情,可聚焦于函數本身。不用像面向對象編程中那樣必須牢記整個(gè)對象圖,這樣極大地簡(jiǎn)化了編程開(kāi)發(fā)。

生態(tài)系統和工具鏈

一種編程語(yǔ)言可能本身并沒(méi)有多少亮點(diǎn),但如果其具有大型的生態(tài)系統,這會(huì )令語(yǔ)言更具吸引力。具備良好的軟件庫,可以節省數月乃至數年的開(kāi)發(fā)工作。

顯著(zhù)的例子就是 JavaScript 和 Python。

速度

語(yǔ)言的編譯速度如何?程序的啟動(dòng)速度如何?運行時(shí)的性能如何?所有這些都是影響評判中的考慮因素。

誕生年代

盡管并非絕對,通常新推出的語(yǔ)言要比原先的語(yǔ)言更好。只是因為新語(yǔ)言會(huì )吸取了前輩的經(jīng)驗教訓。

 C++    

下面從最糟糕、也可能是計算機科學(xué)中最大錯誤的 C++ 語(yǔ)言開(kāi)始。當然,我并不認為 C++ 是一種很好的現代編程語(yǔ)言。但 C++ 當前依然得到廣泛應用,在此必須提及。

語(yǔ)言家族:C

?? 語(yǔ)言特性

C++ 可稱(chēng)為糟糕透頂的語(yǔ)言……如果項目局限于 C,意味著(zhù)不會(huì )有任何機會(huì )被 C++ 愚蠢的“對象模型”搞砸。

—— Linux 創(chuàng )立者 Linus Torvalds

C++ 中填充了各種特性,力圖無(wú)所不能,但在在其中任何一項上都不能說(shuō)出色。C++ 支持 goto、指針、引用、面向對象編程、操作符重載,以及各種非生產(chǎn)特性。

為什么說(shuō) C++ 不好?在我看來(lái),最大問(wèn)題在于 C++ 頗具年頭了。C++ 是在 1979 年設計的。在當時(shí)設計者缺少經(jīng)驗,關(guān)注點(diǎn)發(fā)散,雖然所添加的特性在當時(shí)看來(lái)是似乎好的做法。C++ 得到了非常廣泛的使用,這意味著(zhù)為其中支持各種用例而添加了更多特性,導致特性成堆。

?? 速度

C++ 的編譯時(shí)間出奇的慢,甚至比 Java 慢很多,盡管與 Scala 不相上下。

但在運行時(shí)性能和啟動(dòng)時(shí)間上,C++ 程序表現非常優(yōu)秀。

?? 生態(tài)系統和工具

上圖的推文給出了很好的解釋。C++ 編譯器的錯誤信息對新手并不友好。通常并未指出導致錯誤的確切原因,需要開(kāi)發(fā)人員花時(shí)間查找。

???? 垃圾回收

我曾希望在 C++0x 標準中至少考慮可選地支持垃圾回收,但這在技術(shù)上存在問(wèn)題。

—— C++ 的創(chuàng )建者 Bjarne Stroustrup

垃圾回收從未添加到 C++ 中,而手工內存管理非常易于出錯。開(kāi)發(fā)人員必須操心如何手工釋放和分配內存。我對使用非垃圾回收語(yǔ)言的經(jīng)歷記憶深刻,其中大量的缺陷在當前支持垃圾回收語(yǔ)言中可輕易避免。

?? 面向對象編程的失敗嘗試

我提出了“面向對象”一詞,但并沒(méi)有沒(méi)有顧及 C++。

—— 面向對象編程的創(chuàng )建者 Alan Kay

面向對象編程是一項很好的技術(shù),出現于上世紀六十年代后期,當時(shí) C++ 剛出現。不幸的是,不同于 Smalltalk 等語(yǔ)言,C++ 在實(shí)現面向對象編程中出現了幾個(gè)致命錯誤,導致好的理念變成噩夢(mèng)。

好的一方面是,不同于 Java,至少在 C++ 中面向對象是可選的。

???? 學(xué)習難度

C++ 是一種復雜的低層(low level)語(yǔ)言,不具備任何自動(dòng)內存管理機制。由于特性紛雜,初學(xué)者必須花費大量時(shí)間學(xué)習。

?? 并發(fā)

C++ 設計用于單核計算時(shí)代,只支持簡(jiǎn)單的并發(fā)機制,這還是在近十年中添加的。

?? 錯誤處理

拋出并捕獲錯誤是 C++ 的首選錯誤處理機制。

?? 不可變性

未內置對不可變數據結構的支持。

?? 空值

C++ 中所有引用均可為空值。

評判

C++ 的初衷是成為更好的 C 語(yǔ)言,但這一初衷并未實(shí)現。

系統編程是 C++ 的最適合使用場(chǎng)景。但考慮到已具有 Rust 和 Go 等更好、更現代的替代語(yǔ)言,系統完全可以不用 C++ 實(shí)現。不管讀者同意與否,我不認為 C++ 具有任何優(yōu)點(diǎn)。

是該終結 C++ 的時(shí)候了。

  Java    

Java 是自 MS-DOS 以來(lái)計算機領(lǐng)域中最令人困擾的事情。

—— 面向對象編程創(chuàng )始人 Alan Kay

Java 出現在 1995 年,比 C++ 晚了 16 年。Java 是更簡(jiǎn)單的編程語(yǔ)言,由此得到廣泛使用。

語(yǔ)言家族:C。

?? 垃圾回收

相比 C++,Java 的最大優(yōu)點(diǎn)是具有垃圾回收,這極大地消除了各類(lèi)軟件缺陷。

?? 生態(tài)系統

Java 已經(jīng)存在很長(cháng)時(shí)間,在后端開(kāi)發(fā)領(lǐng)域形成了大型生態(tài)系統,極大地降低了開(kāi)發(fā)負擔。

?? 面向對象語(yǔ)言

本文不會(huì )深入探討面向對象編程的不足。詳細分析可閱讀本文作者的另一篇文章,“面向對象編程:億萬(wàn)美元災難”。

在此給出計算機科學(xué)中一些最為杰出人士的看法:

抱歉,我多年前使用了“對象”一詞。該詞使得很多人聚焦于一個(gè)更狹義的理念,雖然更廣義的理念是消息傳遞。

—— 面向對象編程的創(chuàng )始人 Alan Kay

Alan Kay 是對的,許多主流面向對象編程語(yǔ)言并未找準關(guān)注點(diǎn)。它們聚焦于類(lèi)和對象,而忽視了消息傳遞。幸運的是,Erlang 和 Elixir 等一些現代編程語(yǔ)言找準了方向。

受面向對象編程影響的編程語(yǔ)言,會(huì )導致計算機軟件冗長(cháng)、可讀性不好、描述性差、難修改和維護。

—— Richard Mansfield

所有使用 Java、C# 等面向對象編程語(yǔ)言的開(kāi)發(fā)人員,如果曾具有使用非面向對象編程語(yǔ)言的經(jīng)驗,對此應深有體會(huì )。

?? 速度

大家都知道,Java 運行在 JVM 之上,而 JVM 的啟動(dòng)速度是出名的慢。我曾看到有運行在 JVM 上的程序耗時(shí) 30 多秒才啟動(dòng)起來(lái)。對于現代云原生程序,這是不可接受的。

一個(gè)大型項目,如果編譯速度慢,就會(huì )對開(kāi)發(fā)人員的生產(chǎn)效率產(chǎn)生顯著(zhù)影響。Java、Scala 等 JVM 語(yǔ)言存在同樣的問(wèn)題。

但從好的一面說(shuō),JVM Runtime 的性能還算不錯。

?? 學(xué)習難度

盡管 Java 是一種相當簡(jiǎn)單的語(yǔ)言,但 Java 以面向對象編程為主,這使得 Java 很難做到優(yōu)秀。編寫(xiě)一個(gè)簡(jiǎn)單的 Java 程序可信手拈來(lái),但是掌握如何編寫(xiě)可靠、可維護的面向對象代碼,則需要十數年的 Java 功力。

?? 并發(fā)

Java 設計于單核計算時(shí)代,和 C++ 一樣,僅支持基本的并發(fā)特性。

?? 空值

Java 中,所有引用均可為空值。

?? 錯誤處理

拋出并捕獲錯誤是 Java 的首選錯誤處理機制。

?? 不可變性

未內置對不可變數據結構的支持。

判定

Java 在剛推出時(shí),的確是一種很好的編程語(yǔ)言。但遺憾的是不同于 Scala 等語(yǔ)言,Java 始終專(zhuān)注于面向對象編程。Java 編程嚴重受模板代碼的影響,冗余代碼多。

Java 應該退居二線(xiàn)了。

   C#      

C# 和 Java 并沒(méi)有本質(zhì)上的差異。C# 的早期版本,就是微軟的 Java 實(shí)現。

C# 具有 Java 的大部分優(yōu)點(diǎn)。C# 于 2000 年推出,比 Java 晚 5 年,借鑒了 Java 的經(jīng)驗教訓。

語(yǔ)言家族:C

?? 語(yǔ)法

C# 在語(yǔ)法上一直保持略微領(lǐng)先 Java。盡管是一種面向對象語(yǔ)言,但 C# 在解決模板代碼問(wèn)題上比 Java 有所改進(jìn)。很高興看到 C# 每個(gè)新版本都能改進(jìn)語(yǔ)法。例如,添加了表達體函數成員(expression-bodied function members)、模式匹配、元組等特性。

?? 面向對象語(yǔ)言

和 Java 一樣,C# 主要針對面向對象編程。面向對象編程的缺點(diǎn)如上所列,在此不再詳述。下面列出一些知名人士的觀(guān)點(diǎn)。

我認為相比函數式語(yǔ)言,面向對象語(yǔ)言中缺失可重用性。問(wèn)題在于,面向對象語(yǔ)言需要處理其所提供的所有隱含(implicit)環(huán)境。盡管我們想要的只是一根香蕉,但卻得到了一只握著(zhù)香蕉的大猩猩,甚至是整個(gè)叢林。

—— Erlang 的創(chuàng )建者 Joe Armstrong

我完全同意這個(gè)說(shuō)法,相比函數式編程,命令式編程非常難以重用面向對象代碼。

面向對象編程提供了對正確做法的一個(gè)反面教材……

—— 計算機科學(xué)先驅 Edsger W. Dijkstra

從我自己使用面向對象和非面向對象編程的經(jīng)驗看,我完全同意面向對象代碼更難以正確實(shí)現功能。

?? 多范式(Multi-paradigm)

C# 聲稱(chēng)是一種多范式語(yǔ)言,尤其是聲稱(chēng)支持函數式編程,但我并不同意。對函數提供一流支持(first-class functions),并不足以稱(chēng)之為函數式語(yǔ)言。

那么什么語(yǔ)言可稱(chēng)為具備函數式特性?應至少內置支持不可變數據結構、模式識別、組合函數的管道操作符、代數數據類(lèi)型(ADT)等特性。

?? 并發(fā)

和 Java 一樣,C# 創(chuàng )立于單核計算時(shí)代,僅提供基本的并發(fā)支持。

?? 空值

NullsC# 中,所有引用均可為空。

?? 錯誤處理

拋出并捕獲錯誤是 C# 的首選錯誤處理機制。

?? 不可變性

未內置對不可變數據結構的支持。

評判

盡管我本人的職業(yè)生涯中主要使用的是 C#,但還是對這種語(yǔ)言評價(jià)不高。與對 Java 的評判一樣,我建議讀者尋找更現代的替代語(yǔ)言。C# 在本質(zhì)上依然是 Java,只是具有更現代的語(yǔ)法。不幸的是,C# 本身并不“sharp”。

Python

Python 早在 1991 年提出,和 JavaScript 并稱(chēng)當前使用最廣的兩種語(yǔ)言。

語(yǔ)言家族:C

?? 生態(tài)系統

Python 軟件庫幾乎無(wú)所不能。不同于 JavaScript,Python 不能用于 Web 前端開(kāi)發(fā),但大規模的數據科學(xué)軟件庫彌補了這方面的不足。

?? 學(xué)習難度

Python 語(yǔ)言非常簡(jiǎn)單,初學(xué)者數周就能上手。

?? 類(lèi)型系統

Python 是動(dòng)態(tài)類(lèi)型的,因此談不上需要類(lèi)型系統。

?? 速度

Python 是一種解釋性語(yǔ)言,性能慢。對性能有嚴格要求的程序,可使用 Cython 替代原生的 Python。

相對于原生語(yǔ)言,Python 的啟動(dòng)也相當慢。

?? 工具

對比其他的現代編程語(yǔ)言,難免會(huì )對 Python 的依賴(lài)管理頗為失望。目前存在 pip、pipenv、virtualenv、pip freeze 等工具。相比之下,JavaScript 只需要 NPM 這一種工具。

?? 并發(fā)

Python 在創(chuàng )建時(shí)并未全面考慮并發(fā),僅提供基本的并發(fā)特性。

?? 空值

Python 中所有引用均可為空。

?? 錯誤處理

拋出并捕獲錯誤是 Python 的首選錯誤處理機制。

?? 不可變性

未內置對不可變數據結構的支持。

評判

很不幸,Python 并不提供對函數式編程的支持。函數式編程非常適合處理數據科學(xué)所面對的問(wèn)題。即便是在 Python 擅長(cháng)的 Web 爬蟲(chóng)領(lǐng)域,Elixir 等函數式語(yǔ)言表現更好。

我并不推薦使用 Python 完成大型項目,該語(yǔ)言在構建中并未充分地考慮軟件工程。

如果有更好的選擇,不推薦在數據科學(xué)之外使用 Python。在數據科學(xué)領(lǐng)域,Julia 可能是 Python 的很好替代,盡管相比 Python 而言,Julia 的生態(tài)系統近乎不存在。

   Rust   

Rust 是一種現代低層語(yǔ)言,最初設計用于替代 C++。

語(yǔ)言家族:C

?? 速度

運行快速是 Rust 設計所秉持的初衷。在編譯性能上,Rust 程序要慢于 Go 程序,但運行時(shí)性能比 Go 稍快。

?? 空值

至此,本文推薦列表中終于出現支持現代空值的語(yǔ)言了。Rust 中沒(méi)有 null 或 nil 值,開(kāi)發(fā)人員使用 Option 模式。

// 源代碼: https://doc.rust-lang.org/rust-by-example/std/option.html// 返回值或者是 T 類(lèi)型的 Some,或是 None。enum Option{ Some(T), None,}// 整數除法不會(huì )出錯。fn checked_division(dividend: i32, divisor: i32) -> Option{ if divisor == 0 { // 錯誤表示為 None。None } else { // 結果使用 Some 封裝。Some(dividend / divisor) }}// 該函數用于處理失敗的除操作。fn try_division(dividend: i32, divisor: i32) { // 與其他枚舉一樣,Option 值可模式匹配。match checked_division(dividend, divisor) { None => println!('{} / {} failed!', dividend, divisor), Some(quotient) => { println!('{} / {} = {}', dividend, divisor, quotient) }, }

?? 錯誤處理

Rust 的錯誤處理引入了現代函數式方法,使用特定的 Result 類(lèi)型,聲明可能會(huì )產(chǎn)生失敗的操作。Result 模式非常類(lèi)似于 Option 模式,只是在 None 的情況下依然有值。

// 結果或者是 T 類(lèi)型的 OK 函數值,或是 E 類(lèi)型的 Err 函數值。enum Result<T,E> { Ok(T), Err(E),}// 存在失敗可能的函數。fn random() -> Result<i32, String> { let mut generator = rand::thread_rng(); let number = generator.gen_range(0, 1000); if number <= 500 { Ok(number) } else { Err(String::from(number.to_string() + ' should be less than 500')) }}// 處理函數的結果。match random() { Ok(i) => i.to_string(), Err(e) => e,

?? 內存管理

在本文列出的現代編程語(yǔ)言中,Rust 是唯一不提供垃圾回收的。Rust 迫使開(kāi)發(fā)人員去考慮如何實(shí)現底層的內存管理,這影響了開(kāi)發(fā)人員的效率。

?? 并發(fā)

由于 Rust 中缺少垃圾回收,因此實(shí)現并發(fā)是相當困難的。開(kāi)發(fā)人員必須考慮“裝箱”(boxing)和“釘住”(Pinning)。這在具有垃圾回收機制的語(yǔ)言中,通常是自動(dòng)完成的。

?? 不可變性

未內置對不可變數據結構的支持。

?? 低層語(yǔ)言

作為一種低層語(yǔ)言,開(kāi)發(fā)人員的生產(chǎn)效率無(wú)法其他高層語(yǔ)言相比。同時(shí),語(yǔ)言的學(xué)習難度明顯增大。

評判

Rust 非常適合系統編程。盡管比 Go 更復雜,但 Rust 提供了強大的類(lèi)型系統。Rust 提供了現代的空值替換和錯誤處理方法。

為什么本文將 Rust 排在 TypeScript 和 JavaScript 之后?Rust 是一種設計用于系統編程的低層語(yǔ)言,并非后端和 Web API 開(kāi)發(fā)的最適合選項。Rust 缺少垃圾回收機制,未內置對不可變數據結構的支持。

TypeScript

TypeScript 語(yǔ)言編譯為 JavaScript,通過(guò)對 JavaScript 添加靜態(tài)類(lèi)型,意在成為一種“更好的 JavaScript”。類(lèi)似于 JavaScript,TypeScript 同樣用于前端和后端開(kāi)發(fā)。

TypeScript 由同是 C# 設計者的 Anders Hejlsberg 設計的,因此代碼看上去非常類(lèi)似 C#,可認為是一種用于瀏覽器的 C#。

語(yǔ)言家族:C。

?? JavaScript 的超集

TypeScript 將自己定位為 JavaScript 的超集,這有助于人們采用。畢竟大多數人對 JavaScript 耳熟能詳。

但作為 JavaScript 的超集,更多程度上是一種缺點(diǎn)。這意味著(zhù) TypeScript 繼承了 JavaScript 的全部問(wèn)題,局限于 JavaScript 所有的不良設計決策。

例如,應該沒(méi)有開(kāi)發(fā)人員喜歡 this 關(guān)鍵詞吧。但 TypeScript 依然刻意原封照搬。

再有,其類(lèi)型系統時(shí)常令人感到奇怪。

[] == ![]; // -> 為真NaN === NaN; // -> 為假!

換句話(huà)說(shuō),TypeScript 具有 JavaScript 的所有缺點(diǎn)。一種糟糕語(yǔ)言的超集并不會(huì )變身成為一種優(yōu)秀的語(yǔ)言。

?? 生態(tài)系統

TypeScript 完全分享了 JavaScript 龐大的生態(tài)系統。這是其最大優(yōu)點(diǎn)。特別是相比 Python 等語(yǔ)言,NPM 非常好用。

缺點(diǎn)在于,并非所有的 JavaScript 軟件庫都可在 TypeScript 中使用,例如 Rambda/Immutable.js 等。

?? 類(lèi)型系統

個(gè)人感覺(jué),TypeScript 的類(lèi)型系統毫無(wú)亮點(diǎn)。

好的一面是甚至提供對 ADT 的支持。例如下面給出的差別聯(lián)合(discriminated union)類(lèi)型:???????

// 源代碼來(lái)自 https://stackoverflow.com/questions/33915459/algebraic-data-types-in-typescriptinterface Square { kind: 'square'; size: number;}interface Rectangle { kind: 'rectangle'; width: number; height: number;}interface Circle { kind: 'circle'; radius: number;}type Shape = Square | Rectangle | Circle;function area(s: Shape) { switch (s.kind) { case 'square': return s.sizes.size; case 'rectangle': return s.heights.width; case 'circle': return Math.PI * s.radius ** 2;

下面是使用 ReasonML 實(shí)現的同樣代碼:???????

type shape = | Square(int) | Rectangle(int, int) | Circle(int);let area = fun | Square(size) => sizesize | Rectangle(width, height) => widthheight | Circle(radius) => 2piradius;

差別聯(lián)合類(lèi)型是在 TypeScript 2.0 中增添的,TypeScript 的語(yǔ)法尚未企及函數式語(yǔ)言的高度。例如,在 switch 中的字符串匹配易于出錯,編譯器無(wú)法在大小寫(xiě)錯誤時(shí)給出警告。

TypeScript 僅提供基本的類(lèi)型推斷。此外在使用 TypeScript 時(shí),any 關(guān)鍵字的出現頻次難免過(guò)高。

?? 空值

TypeScript 2.0 添加了對不可為空(non-nullable)類(lèi)型的支持,使用編譯器選項 --strictNullChecks 啟用。但使用不可為空類(lèi)型并非編程默認,也并非 TypeScript 的慣用做法。

?? 錯誤處理

TypeScript 中,使用拋出和捕獲異常處理錯誤。

?? 新的 JavaScript 特性

新酷特性首先在 JavaScript 中得到支持,然后才是 TypeScript。實(shí)驗特性可使用 Babel 在 JavaScript 中得到支持,而在 TypeScript 中則無(wú)此功能。

?? 不可變性

TypeScript 對不可變數據結構的處理,要顯著(zhù)劣于 JavaScript。JavaScript 開(kāi)發(fā)人員可使用支持不可變性處理的軟件庫,但 TypeScript 開(kāi)發(fā)人員通常必須依賴(lài)原始數組或對象展開(kāi)操作符(spread operator),即寫(xiě)入時(shí)復制(copy-on-write)。???????

const oldArray = [1, 2];const newArray = [...oldArray, 3];const oldPerson = { name: { first: 'John', last: 'Snow' }, age: 30};// 執行對象深拷貝(deep copy)非常繁瑣。const newPerson = { ...oldPerson, name: { ...oldPerson.name, first: 'Jon' }

正如上面代碼所示,原生擴展操作符并不支持深拷貝(deep copy),而手工擴展深度對象非常繁瑣。大型數組和對象的拷貝的性能也非常不好。

但 TypeScript 中,readonly 關(guān)鍵字非常好用,用于定義屬性是不可變的。雖然如此,TypeScript 要對不可變數據結構提供很好支持,依然需要很多工作。

JavaScript 提供了一些操作不可變數據的很好軟件庫,例如 Rambda/Immutable.js。但是,實(shí)現此類(lèi)軟件庫對 TypeScript 的支持并非易事。

?? TypeScript 對比 React

相比 Clojure 等從設計上考慮到不可變數據處理的語(yǔ)言,在 JavaScript 和 TypeScript 中不可變數據的處理相對更為困難。

—— 原文引用自 React 官方文檔

繼續說(shuō)缺點(diǎn)。前端 Web 開(kāi)發(fā)推薦使用 React。

React 并未針對 TypeScript 設計。最初,React 是針對函數式語(yǔ)言設計的,本文稍后會(huì )詳細介紹。二者在編程范式上存在沖突,TypeScript 是面向對象編程優(yōu)先的,而 React 是函數優(yōu)先的。

React 中,函數參數 props 是不可變的;而 TypeScript 中,沒(méi)有內置提供適用的不可變數據結構支持。

在開(kāi)發(fā)中,TypeScript 相比 JavaScript、React 的唯一優(yōu)點(diǎn)是,無(wú)需操心 PropTypes。TypeScript 是否是 JavaScript 的超集?這取決于開(kāi)發(fā)人員的認識。至少我認為是的。做為超集的最大優(yōu)點(diǎn),是可接入整個(gè) JavaScript 生態(tài)系統。

為什么 JavaScript 的超集語(yǔ)言備受關(guān)注?這與 Java、C# 廣為采用是同樣的原因,是因為背后有市場(chǎng)營(yíng)銷(xiāo)預算充足的大廠(chǎng)在提供支持。

評判

盡管 TypeScript 常被認為是“更好的 JavaScript”,但我依然評判其劣于 JavaScript。TypeScript 相比 JavaScript 的優(yōu)點(diǎn)被夸大了,尤其是對于使用 React 做前端 Web 開(kāi)發(fā)。

TypeScript 保留了 JavaScript 的所有不足,實(shí)際上也繼承了 JavaScript 中數十年積累不良設計決策,的確并非一種成功的交付,

Go    

Go 設計上主要考慮了提高多核處理器和大規模代碼庫的編程效率。Go 的設計者們當時(shí)任職于谷歌,因對 C++ 的共同不喜而得到靈感。

語(yǔ)言家族:C。

?? 并發(fā)

并發(fā)是 Go 的殺手級特性。Go 從本質(zhì)上就是為并發(fā)而構建。和 Erlang/Elixir 一樣,Go 使用郵箱模型(Mailbox)實(shí)現并發(fā)。不幸的是,goroutines 并未提供 Erlang/Elixir 進(jìn)程那樣的統一容錯特性。換句話(huà)說(shuō),goroutine 中的異常將導致整個(gè)程序宕機,而 Elixir 進(jìn)程中的異常只會(huì )導致當前進(jìn)程終止。

?? ?? 速度編譯

速度是谷歌創(chuàng )建 Go 的一個(gè)重要考慮。有個(gè)笑話(huà),谷歌利用 C++ 編譯代碼的時(shí)間就創(chuàng )建出了 Go。

Go 是一種高效的語(yǔ)言。Go 程序的啟動(dòng)時(shí)間非???。Go 編譯為原生代碼,所以運行時(shí)速度也非???。

?? 學(xué)習難度

Go 是一種簡(jiǎn)單的語(yǔ)言,如果得到有經(jīng)驗前輩的指導,新手能在一個(gè)月內掌握。

?? 錯誤處理

Go 并不支持異常,由開(kāi)發(fā)人員顯式處理各種可能的錯誤。和 Rust 類(lèi)似,Go 也返回兩個(gè)值,一個(gè)是調用的結果,另一個(gè)是可能的錯誤值。如果一切運行正常,返回的錯誤值是 nil。

?? 不支持面向對象編程

雖然這么說(shuō)有人會(huì )反對,但我個(gè)人認為,不支持面向對象特性是很大的優(yōu)勢。

重申 Linux Torvalds 的觀(guān)點(diǎn):

C++ 是一種很糟的(面向對象)語(yǔ)言……將項目局限于 C,意味著(zhù)整個(gè)項目不會(huì )因為任何愚蠢的 C++“對象模型”而搞砸。

—— Linux 創(chuàng )建者 Linus Torvalds

Linus Torvalds 公開(kāi)對 C++ 和面向對象編程持批評態(tài)度。限制編程人員在可選的范圍內,是他完全正確的一面。事實(shí)上,編程人員的選擇越少,代碼也會(huì )更穩定。

在我看來(lái),Go 可以回避了許多面向對象特性,免于重蹈 C++ 的覆轍。

?? 生態(tài)系統

一些標準庫的確很笨重。大部分并不符合 Go 返回帶外(out-of-band,OOB)錯誤的自身哲學(xué)。例如,有的庫對索引返回 -1 值,而非 (int, error)。還有一些庫依賴(lài)全局狀態(tài),例如 flag 和 net/http。

Go 的軟件庫缺少標準化。例如在錯誤時(shí),有的庫返回 (int, error),也有軟件庫返回 -1 等值。還有一些庫依賴(lài)標識等全局狀態(tài)。

Go 的生態(tài)系統規模遠比不上 JavaScript。

?? 類(lèi)型系統

幾乎所有的現代編程語(yǔ)言都具有某種形式的泛型,其中包括 C# 和 Java,甚至是 C++ 也提供模板類(lèi)。泛型支持開(kāi)發(fā)人員重用不同類(lèi)型的函數實(shí)現。如果不支持泛型,那么開(kāi)發(fā)人員就必須對整型、雙精度和浮點(diǎn)型單獨實(shí)現加法函數,這將導致大量的代碼冗余。換句話(huà)說(shuō),Go 缺失對泛型的支持導致了大量冗余代碼。正如有人指出的,“Go”是“去寫(xiě)一些模板代碼”(Go write some boilerplate)的縮寫(xiě)。

?? 空值

不幸的是,即使更安全的空值替代方案已存在數十年,Go 依然在語(yǔ)言中添加了空值。

?? 不可變性

未內置對不可變數據結構的支持。

評判

Go 并非一種好的語(yǔ)言,但也談不上不好,只是不夠優(yōu)秀。使用一種并不優(yōu)秀的語(yǔ)言時(shí)需謹慎,因為這可能會(huì )導致我們在隨后的二十年中陷入困境。

Will Yager 的博客文章“Why Go Is No Good”

如果你并非供職于谷歌,也沒(méi)有面對類(lèi)似谷歌的用例,那么 Go 可能并非好的選擇。Go 是一種最適合系統編程的簡(jiǎn)單語(yǔ)言,但并非 API 開(kāi)發(fā)的好選擇。原因是因為我們有更多更好的替代語(yǔ)言,本文稍后介紹。

我認為總體而言,盡管 G 的類(lèi)型系統略弱,但比 Rust 還是略好。Go 是一種簡(jiǎn)單的語(yǔ)言,非???,易于學(xué)習,并且具有出色的并發(fā)功能。當然,Go 成功地實(shí)現了做為“更好的 C++”這一設計目標。

最佳系統語(yǔ)言獎授予 Go

實(shí)至名歸,Go 是系統編程的理想選擇。Go 是一種低層語(yǔ)言,使用 Go 構建的大量成功項目,例如 Kubernetes,Docker 和 Terraform,證明其非常適合系統編程。

JavaScript

作為當前最流行的編程語(yǔ)言,JavaScript 無(wú)需過(guò)多介紹。

當然,將 JavaScript 排在 Rust、TypeScript 和 Go 之前是正確的。下面給出原因。

語(yǔ)言家族:C

?? ?? 生態(tài)系統

生態(tài)系統是 JavaScript 的最大優(yōu)勢。我們能想到的所有,,包括 Web 的前端和后端開(kāi)發(fā),CLI 編程、數據科學(xué),甚至是機器學(xué)習,都可使用 JavaScript。JavaScript 可能具有提供任何功能的軟件庫。

?? 學(xué)習難度

JavaScript 和 Python 都是非常容易學(xué)習的編程語(yǔ)言。幾周就能上手做項目。

?? 類(lèi)型系統

和 Python 類(lèi)似,JavaScript 是動(dòng)態(tài)類(lèi)型的。無(wú)需過(guò)多解釋?zhuān)瞧漕?lèi)型系統時(shí)??雌饋?lái)很奇怪:

[] == ![] // -> 為真NaN === NaN; // -> 為假[] == '' // -> 為真[] == 0 // -> 為真

?? 不可變性

在 TypeScript 一節中已經(jīng)介紹,展開(kāi)操作符(spread operator)會(huì )影響性能,甚至并沒(méi)有在拷貝對象時(shí)執行深拷貝。盡管有 Ramda/Immutable.js 等軟件庫,但 JavaScript 缺少對不可變數據結構的內建支持。

?? JavaScript 并非針對響應式設計的

在 JavaScript 中使用 React,必須借助 PropTypes。但這也意味著(zhù)必須去維護 PropTypes,這會(huì )導致災難性后果。

此外,如果在編程中不加注意的話(huà),可能會(huì )導致嚴重的性能問(wèn)題。例如:

<HugeList options=[] />

這個(gè)看上去無(wú)害的代碼會(huì )導致嚴重性能問(wèn)題。因為在 JavaScript 中, [] != []。上面的代碼會(huì )導致 HugeList 在每一次更新時(shí)重渲染,盡管 options 值并未發(fā)生變化。此類(lèi)問(wèn)題會(huì )不斷疊加,直到用戶(hù)界面最終無(wú)法響應。

?? 關(guān)鍵字 this

關(guān)鍵字 this 應該是 JavaScript 中的最大反特性。其行為持續表現不一致,在不同的情況下可能意味完全不同,其行為甚至取決于誰(shuí)調用了指定的函數。使用 this 關(guān)鍵字通常會(huì )導致一些細微而奇怪的錯誤,難以調試。

?? 并發(fā)

JavaScript 使用事件循環(huán)支持單線(xiàn)程并發(fā),無(wú)需考慮加鎖等線(xiàn)程同步機制。盡管 JavaScript 在構建時(shí)并未考慮并發(fā)性,但與大多數其他語(yǔ)言相比,更易于實(shí)現并發(fā)代碼。

?? 新的 JavaScript 特性

相比 TypeScript,新特性能更快地在 JavaScript 中支持。即便是實(shí)驗性特性,也可使用 Bable 支持在 JavaScript 中使用。

?? 錯誤處理

Error handling拋出并捕獲錯誤是 JavaScript 的首選錯誤處理機制。

評判

JavaScript 并非一種很好設計的語(yǔ)言。JavaScript 的最初版本僅用十天就拼湊出來(lái),盡管在后期版本中修正了許多缺點(diǎn)。

拋開(kāi)上述缺點(diǎn),JavaScript 依然是全棧 Web 開(kāi)發(fā)和很好選擇。如果加以適當的代碼修煉和分析,JavaScript 是一種很好的語(yǔ)言。

原文鏈接:

These Modern Programming Languages Will Make You Suffer

https://www.infoq.cn/article/9VXbENMFH9Y65VCOI4D1

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
幫你提升 Python 的 27 種編程語(yǔ)言
博采 27 門(mén)語(yǔ)言之長(cháng),提升 Python 的能力
程序員不糾結:九大非主流頂尖編程語(yǔ)言!
為什么我們不再發(fā)明編程語(yǔ)言了?
一位“老程序員”的反思:C、Python、Java 不可兼得,專(zhuān)心學(xué)好一門(mén)編程語(yǔ)言就行!
現代編程語(yǔ)言大 PK,2020 年開(kāi)發(fā)者關(guān)心的七大編程語(yǔ)言
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久