[zz]Kotlin 和 Checked Exception

Kotlin 和 Checked Exception

最近 JetBrains 的 Kotlin 語(yǔ)言忽然成了熱門(mén)話(huà)題。國(guó)內(nèi)小編們傳言說(shuō),Kotlin 取代了 Java,成為了 Android 的“欽定語(yǔ)言”,很多人聽(tīng)了之后熱血沸騰。初學(xué)者們也開(kāi)始注意到 Kotlin,問(wèn)出各種“傻問(wèn)題”,很“功利”的問(wèn)題,比如“現(xiàn)在學(xué) Kotlin 是不是太早了一點(diǎn)?” 結(jié)果引起一些 Kotlin 老鳥(niǎo)們的鄙視。當(dāng)然也有人來(lái)信,請(qǐng)求我評(píng)價(jià) Kotlin。
對(duì)于這種評(píng)價(jià)語(yǔ)言的請(qǐng)求,我一般都不予理睬的。作為一個(gè)專(zhuān)業(yè)的語(yǔ)言研究者,我的職責(zé)不應(yīng)該是去評(píng)價(jià)別人設(shè)計(jì)的語(yǔ)言。然而瀏覽了 Kotlin 的文檔之后,我發(fā)現(xiàn) Kotlin 的設(shè)計(jì)者誤解了一個(gè)重要的問(wèn)題——關(guān)于是否需要 checked exception。對(duì)于這個(gè)話(huà)題我已經(jīng)思考了很久,覺(jué)得有必要分享一下我對(duì)此的看法,避免誤解的傳播,所以我還是決定寫(xiě)一篇文章。
可以說(shuō)我這篇文章針對(duì)的是 checked exception,而不是 Kotlin,因?yàn)橥瑯拥膯?wèn)題也存在于 C# 和其它一些語(yǔ)言。
冷靜一下
在進(jìn)入主題之前,我想先糾正一些人的誤解,讓他們冷靜下來(lái)。我們首先應(yīng)該搞清楚的是,Kotlin 并不是像有些國(guó)內(nèi)媒體傳言的那樣,要“取代 Java 成為 Android 的官方語(yǔ)言”。準(zhǔn)確的說(shuō),Kotlin 只是得到了 Android 的“官方支持”,所以你可以用 Kotlin 開(kāi)發(fā) Android 程序,而不需要繞過(guò)很多限制??梢哉f(shuō) Kotlin 跟 Java 一樣,都是 Android 的官方語(yǔ)言,但 Kotlin 不會(huì)取代 Java,它們是一種并存關(guān)系。
這里我不得不批評(píng)一下有些國(guó)內(nèi)技術(shù)媒體,他們似乎很喜歡片面報(bào)道和歪曲夸大事實(shí),把一個(gè)平常的事情吹得天翻地覆。如果你看看國(guó)外媒體對(duì) Kotlin 的報(bào)道,就會(huì)發(fā)現(xiàn)他們用詞的迥然不同:
Google’s Java-centric Android mobile development platform is adding the Kotlin language as an officially supported development language, and will include it in the Android Studio 3.0 IDE.

譯文:Google 的以 Java 為核心的 Android 移動(dòng)開(kāi)發(fā)平臺(tái),加入了 Kotlin 作為官方支持的開(kāi)發(fā)語(yǔ)言。它會(huì)被包含到 Android Studio 3.0 IDE 里面。

看明白了嗎?不是“取代了 Java”,而只是給了大家另一個(gè)“選擇”。我發(fā)現(xiàn)國(guó)內(nèi)的技術(shù)小編們似乎很喜歡把“選擇”歪曲成“取代”。前段時(shí)間這些小編們也有類(lèi)似的謠傳,說(shuō)斯坦福大學(xué)把入門(mén)編程課的語(yǔ)言“換成了 JavaScript”,而其實(shí)別人只是另外“增加”了一門(mén)課,使用 JavaScript 作為主要編程語(yǔ)言,原來(lái)以 Java 為主的入門(mén)課并沒(méi)有被去掉。我希望大家在看到此類(lèi)報(bào)道的時(shí)候多長(zhǎng)個(gè)心眼,要分清楚“選擇”和“取代”,不要盲目的相信一個(gè)事物會(huì)立即取代另一個(gè)。
Android 顯然不可能拋棄 Java 而擁抱 Kotlin。畢竟現(xiàn)有的 Android 代碼絕大部分都是 Java 寫(xiě)的,絕大部分程序員都在用 Java。很多人都知道 Java 的好處,所以他們不會(huì)愿意換用一個(gè)新的,未經(jīng)時(shí)間考驗(yàn)的語(yǔ)言。所以雖然 Kotlin 在 Android 上得到了和 Java 平起平坐的地位,想要程序員們從 Java 轉(zhuǎn)到 Kotlin,卻不是一件容易的事情。
我不明白為什么每當(dāng)出現(xiàn)一個(gè) JVM 的語(yǔ)言,就有人歡呼雀躍的,希望它會(huì)取代 Java,似乎這些人跟 Java 有什么深仇大恨。他們已經(jīng)為很多新語(yǔ)言熱血沸騰過(guò)了,不是嗎?Scala,Clojure…… 一個(gè)個(gè)都像中國(guó)古代的農(nóng)民起義一樣,煽動(dòng)一批人起來(lái)造反,而其實(shí)自己都不知道自己在干什么。Kotlin 的主頁(yè)也把“drastically reduce the amount of boilerplate code”作為了自己的一大特色,仿佛是在暗示大家 Java 有很多“boilerplate code”。
如果你經(jīng)過(guò)理性的分析,就會(huì)發(fā)現(xiàn) Java 并不是那么的討厭。正好相反,Java 的有些設(shè)計(jì)看起來(lái)“繁復(fù)多余”,實(shí)際上卻是經(jīng)過(guò)深思熟慮的決定。Java 的設(shè)計(jì)者知道有些地方可以省略,卻故意把它做成多余的。不理解語(yǔ)言“可用性”的人,往往盲目地以為簡(jiǎn)短就是好,多寫(xiě)幾個(gè)字就是丑陋不優(yōu)雅,其實(shí)不是那樣的。關(guān)于 Java 的良好設(shè)計(jì),你可以參考我之前的文章《為 Java 說(shuō)句公道話(huà)》。另外在《對(duì) Rust 語(yǔ)言的分析》里面,我也提到一些容易被誤解的語(yǔ)言可用性問(wèn)題。我希望這些文章對(duì)人們有所幫助,避免他們因?yàn)槠珗?zhí)而扔掉好的東西。
實(shí)際上我很早以前就發(fā)現(xiàn)了 Kotlin,看過(guò)它的文檔,當(dāng)時(shí)并沒(méi)有引起我很大的興趣?,F(xiàn)在它忽然火了起來(lái),我再次瀏覽它的新版文檔,卻發(fā)現(xiàn)自己還是會(huì)繼續(xù)使用 Java 或者 C++。雖然我覺(jué)得 Kotlin 比起 Java 在某些小地方設(shè)計(jì)相對(duì)優(yōu)雅,一致性稍好一些,然而我并沒(méi)有發(fā)現(xiàn)它可以讓我興奮到愿意丟掉 Java 的地步。實(shí)際上 Kotlin 的好些小改進(jìn),我在設(shè)計(jì)自己語(yǔ)言的時(shí)候都已經(jīng)想到了,然而我并不覺(jué)得它們可以成為人們換用一個(gè)新語(yǔ)言的理由。
Checked Exception(CE)的重要性
有幾個(gè)我覺(jué)得很重要的,具有突破性的語(yǔ)言特性,Kotlin 并沒(méi)有實(shí)現(xiàn)。另外我還發(fā)現(xiàn)一個(gè)很重要的 Java 特性,被 Kotlin 的設(shè)計(jì)者給盲目拋棄了。這就是我今天要講的主題:checked exception。我不知道這個(gè)術(shù)語(yǔ)有什么標(biāo)準(zhǔn)的中文翻譯,為了避免引起定義混亂,下文我就把它簡(jiǎn)稱(chēng)為“CE”好了。
先來(lái)科普一下 CE 到底是什么吧。Java 要求你必須在函數(shù)的類(lèi)型里面聲明它可能拋出的異常。比如,你的函數(shù)如果是這樣:
void foo(string filename) throws FileNotFoundException{ if (...) { throw new FileNotFoundException(); } ...}

Java 要求你必須在函數(shù)頭部寫(xiě)上“throws FileNotFoundException”,否則它就不能編譯。這個(gè)聲明表示函數(shù)在某些情況下,會(huì)拋出 FileNotFoundException 這個(gè)異常。由于編譯器看到了這個(gè)聲明,它會(huì)嚴(yán)格檢查你對(duì) foo 函數(shù)的用法。在調(diào)用 foo 的時(shí)候,你必須使用 try-catch 處理這個(gè)異常,或者在調(diào)用的函數(shù)頭部也聲明 “throws FileNotFoundException”,把這個(gè)異常傳遞給上一層調(diào)用者。
try{ foo("blah");} catch (FileNotFoundException e){ ...}

這種對(duì)異常的聲明和檢查,叫做“checked exception”。很多語(yǔ)言(包括 C++,C#,JavaScript,Python……)都有異常機(jī)制,但它們不要求你在函數(shù)的類(lèi)型里面聲明可能出現(xiàn)的異常類(lèi)型,也不使用靜態(tài)類(lèi)型系統(tǒng)對(duì)異常的處理進(jìn)行檢查和驗(yàn)證。我們說(shuō)這些語(yǔ)言里面有“exception”,卻沒(méi)有“checked exception”。
理解了 CE 這個(gè)概念,下面我們來(lái)談?wù)拢篕otlin 和 C# 對(duì) CE 的誤解。
Kotlin 的文檔明確的說(shuō)明,它不支持類(lèi)似 Java 的 checked exception(CE),指出 CE 的缺點(diǎn)是“繁瑣”,并且列舉了幾個(gè)普通程序員心目中“大?!钡奈恼拢胍源藖?lái)證明為什么 Java 的 CE 是一個(gè)錯(cuò)誤,為什么它不解決問(wèn)題,卻帶來(lái)了麻煩。這些人包括了 Bruce Eckel 和 C# 的設(shè)計(jì)者 Anders Hejlsberg。
很早的時(shí)候我就看過(guò) Hejlsberg 的這些言論。他的話(huà)看似有道理,然而通過(guò)自己編程和設(shè)計(jì)語(yǔ)言的實(shí)際經(jīng)驗(yàn),我發(fā)現(xiàn)他并沒(méi)有抓住問(wèn)題的關(guān)鍵。他的論述里有好幾處邏輯錯(cuò)誤,一些自相矛盾,還有一些盲目的臆斷,所以這些言論并沒(méi)能說(shuō)服我。正好相反,實(shí)在的項(xiàng)目經(jīng)驗(yàn)告訴我,CE 是 C# 缺少的一項(xiàng)重要特性,沒(méi)有了 CE 會(huì)帶來(lái)相當(dāng)麻煩的后果。在微軟寫(xiě) C# 的時(shí)候,我已經(jīng)深刻體會(huì)到了缺少 CE 所帶來(lái)的困擾?,F(xiàn)在我就來(lái)講一下,CE 為什么是很重要的語(yǔ)言特性,然后講一下為什么 Hejlsberg 對(duì)它的批評(píng)是站不住腳的。
首先,寫(xiě) C# 代碼時(shí)最讓我頭痛的事情之一,就是 C# 沒(méi)有 CE。每調(diào)用一個(gè)函數(shù)(不管是標(biāo)準(zhǔn)庫(kù)函數(shù),第三方庫(kù)函數(shù),還是隊(duì)友寫(xiě)的函數(shù),甚至我自己寫(xiě)的函數(shù)),我都會(huì)疑惑這個(gè)函數(shù)是否會(huì)拋出異常。由于 C# 的函數(shù)類(lèi)型上不需要標(biāo)記它可能拋出的異常,為了確保一個(gè)函數(shù)不會(huì)拋出異常,你就需要檢查這個(gè)函數(shù)的源代碼,以及它調(diào)用的那些函數(shù)的源代碼……
也就是說(shuō),你必須檢查這個(gè)函數(shù)的整個(gè)“調(diào)用樹(shù)”的代碼,才能確信這個(gè)函數(shù)不會(huì)拋出異常。這樣的調(diào)用樹(shù)可以是非常大的。說(shuō)白了,這就是在用人工對(duì)代碼進(jìn)行“全局靜態(tài)分析”,遍歷整個(gè)調(diào)用樹(shù)。這不但費(fèi)時(shí)費(fèi)力,看得你眼花繚亂,還容易漏掉出錯(cuò)。顯然讓人做這種事情是不現(xiàn)實(shí)的,所以絕大部分時(shí)候,程序員都不能確信這個(gè)函數(shù)調(diào)用不會(huì)出現(xiàn)異常。
在這種疑慮的情況下,你就不得不做最壞的打算,你就得把代碼寫(xiě)成:
try{ foo();} catch (Exception){ ...}

注意到了嗎,這也就是你寫(xiě) Java 代碼時(shí),能寫(xiě)出的最糟糕的異常處理代碼!因?yàn)椴恢?foo 函數(shù)里面會(huì)有什么異常出現(xiàn),所以你的 catch 語(yǔ)句里面也不知道該做什么。大部分人只能在里面放一條 log,記錄異常的發(fā)生。這是一種非常糟糕的寫(xiě)法,不但繁復(fù),而且可能掩蓋運(yùn)行時(shí)錯(cuò)誤。有時(shí)候你發(fā)現(xiàn)有些語(yǔ)句莫名其妙沒(méi)有執(zhí)行,折騰好久才發(fā)現(xiàn)是因?yàn)槟硞€(gè)地方拋出了異常,所以跳到了這種 catch 的地方,然后被忽略了。如果你忘了寫(xiě) catch (Exception),那么你的代碼可能運(yùn)行了一段時(shí)間之后當(dāng)?shù)?,因?yàn)楹鋈怀霈F(xiàn)一個(gè)測(cè)試時(shí)沒(méi)出現(xiàn)過(guò)的異?!?br> 所以對(duì)于 C# 這樣沒(méi)有 CE 的語(yǔ)言,很多時(shí)候你必須莫名其妙這樣寫(xiě),這種做法也就是我在微軟的 C# 代碼里經(jīng)常看到的。問(wèn)原作者為什么那里要包一層 try-catch,答曰:“因?yàn)橹斑@地方出現(xiàn)了某種異常,所以加了個(gè) try-catch,然后就忘了當(dāng)時(shí)出現(xiàn)的是什么異常,具體是哪一條語(yǔ)句會(huì)出現(xiàn)異常,總之那一塊代碼會(huì)出現(xiàn)異?!?如此寫(xiě)代碼,自己心虛,看的人也糊涂,軟件質(zhì)量又如何保證?
那么 Java 呢?因?yàn)?Java 有 CE,所以當(dāng)你看到一個(gè)函數(shù)沒(méi)有聲明異常,就可以放心的省掉 try-catch。所以這個(gè) C# 的問(wèn)題,自然而然就被避免了,你不需要在很多地方疑惑是否需要寫(xiě) try-catch。Java 編譯器的靜態(tài)類(lèi)型檢查會(huì)告訴你,在什么地方必須寫(xiě) try-catch,或者加上 throws 聲明。如果你用 IntelliJ,把光標(biāo)放到 catch 語(yǔ)句上面,可能拋出那種異常的語(yǔ)句就會(huì)被加亮。C# 代碼就不可能得到這樣的幫助。


CE 看起來(lái)有點(diǎn)費(fèi)事,似乎只是為了“讓編譯器開(kāi)心”,然而這其實(shí)是每個(gè)程序員必須理解的事情。出錯(cuò)處理并不是 Java 所特有的東西,就算你用 C 語(yǔ)言,也會(huì)遇到本質(zhì)一樣的問(wèn)題。使用任何語(yǔ)言都無(wú)法逃脫這個(gè)問(wèn)題,所以必須把它想清楚。在《編程的智慧》一文中,我已經(jīng)講述了如何正確的進(jìn)行出錯(cuò)處理。如果你濫用 CE,當(dāng)然會(huì)有不好的后果,然而如果你使用得當(dāng),就會(huì)起到事半功倍,提高代碼可靠性的效果。
Java 的 CE 其實(shí)對(duì)應(yīng)著一種強(qiáng)大的邏輯概念,一種根本性的語(yǔ)言特性,它叫做“union type”。這個(gè)特性只存在于 Typed Racket 等一兩個(gè)不怎么流行的語(yǔ)言里。Union type 也存在于 PySonar 類(lèi)型推導(dǎo)和 Yin 語(yǔ)言里面。你可以把 Java 的 CE 看成是對(duì) union type 的一種不完美的,丑陋的實(shí)現(xiàn)。雖然實(shí)現(xiàn)丑陋,寫(xiě)法麻煩,CE 卻仍然有著 union type 的基本功能。如果使用得當(dāng),union type 不但會(huì)讓代碼的出錯(cuò)處理無(wú)懈可擊,還可以完美的解決 null 指針等頭痛的問(wèn)題。通過(guò)實(shí)際使用 Java 的 CE 和 Typed Racket 的 union type 來(lái)構(gòu)建復(fù)雜項(xiàng)目,我很確信 CE 的可行性和它帶來(lái)的好處。
現(xiàn)在我來(lái)講一下為什么 Hejlsberg 對(duì)于 CE 的批評(píng)是站不住腳的。他的第一個(gè)錯(cuò)誤,俗話(huà)說(shuō)就是“人笨怪刀鈍”。他把程序員對(duì)于出錯(cuò)處理的無(wú)知,不謹(jǐn)慎和誤用,怪罪在 CE 這個(gè)無(wú)辜的語(yǔ)言特性身上。他的話(huà)翻譯過(guò)來(lái)就是:“因?yàn)榇蟛糠殖绦騿T都很傻,沒(méi)有經(jīng)過(guò)嚴(yán)格的訓(xùn)練,不小心又懶惰,所以沒(méi)法正確使用 CE。所以這個(gè)特性不好,是沒(méi)用的!”
他的論據(jù)里面充滿(mǎn)了這樣的語(yǔ)言:
“大部分程序員不會(huì)處理這些 throws 聲明的異常,所以他們就給自己的每個(gè)函數(shù)都加上 throws Exception。這使得 Java 的 CE 完全失效?!?br> “大部分程序員根本不在乎這異常是什么,所以他們?cè)诔绦虻淖钌蠈蛹由?catch (Exception),捕獲所有的異常?!?br> “有些人的函數(shù)最后拋出 80 多種不同的異常,以至于使用者不知道該怎么辦。”……

注意到了嗎,這種給每個(gè)函數(shù)加上 throws Exception
或者 catch (Exception)
的做法,也就是我在《編程的智慧》里面指出的經(jīng)典錯(cuò)誤做法。要讓 CE 可以起到良好的作用,你必須避免這樣的用法,你必須知道自己在干什么,必須知道被調(diào)用的函數(shù)拋出的 exception 是什么含義,必須思考如何正確的處理它們。
另外 CE 就像 union type 一樣,如果你不小心分析,不假思索就拋出異常,就會(huì)遇到他提到的“拋出 80 多種異?!钡那闆r。出現(xiàn)這種情況往往是因?yàn)槌绦騿T沒(méi)有仔細(xì)思考,沒(méi)有處理本來(lái)該自己處理的異常,而只是簡(jiǎn)單的把下層的異常加到自己函數(shù)類(lèi)型里面。在多層調(diào)用之后,你就會(huì)發(fā)現(xiàn)最上面的函數(shù)累積起很多種異常,讓調(diào)用者不知所措,只好傳遞這些異常,造成惡性循環(huán)。終于有人煩得不行,把它改成了“throws Exception”。
我在使用 Typed Racket 的 union type 時(shí)也遇到了類(lèi)似的問(wèn)題,但只要你嚴(yán)格檢查被調(diào)用函數(shù)的異常,盡量不讓它們傳播,嚴(yán)格限制自己拋出的異常數(shù)目,縮小可能出現(xiàn)的異常范圍,這種情況是可以避免的。CE 和 union type 強(qiáng)迫你仔細(xì)的思考,理順這些東西之后,你就會(huì)發(fā)現(xiàn)代碼變得非??b密而優(yōu)雅。其實(shí)就算你寫(xiě) C 代碼或者 JavaScript,這些問(wèn)題是同樣存在的,只不過(guò)這些語(yǔ)言沒(méi)有強(qiáng)迫你去思考,所以很多時(shí)候問(wèn)題被稀里糊涂掩蓋了起來(lái),直到很長(zhǎng)時(shí)間之后才暴露出來(lái),不可救藥。
所以可以說(shuō),這些問(wèn)題來(lái)自于程序員自己,而不是 CE 本身。CE 只提供了一種機(jī)制,至于程序員怎么使用它,是他們自己的職責(zé)。再好的特性被濫用,也會(huì)產(chǎn)生糟糕的結(jié)果。Hejlsberg 對(duì)這些問(wèn)題使用了站不住腳的理論。如果你假設(shè)程序員都是糊里糊涂寫(xiě)代碼,那么你可以得出無(wú)比驚人的結(jié)論:所有用于防止錯(cuò)誤的語(yǔ)言特性都是沒(méi)用的!因?yàn)榭傆腥丝梢詰械讲焕斫膺@些特性的用法,所以他總是可以濫用它們,繞過(guò)它們,寫(xiě)出錯(cuò)誤百出的代碼,所以靜態(tài)類(lèi)型沒(méi)用,CE 沒(méi)用,…… 有這些特性的語(yǔ)言都是垃圾,大家都寫(xiě) PHP 就行了 ;)
Hejlsberg 把這些不理解 CE 用法,懶惰,濫用它的人作為依據(jù),以至于得出 CE 是沒(méi)用的特性,以至于不把它放到 C# 里面。由于某些人會(huì)誤用 CE,結(jié)果就讓真正理解它的人也不能用它。最后所有人都退化到最笨的情況,大家都只好寫(xiě) catch (Exception)
。在 Java 里,至少有少數(shù)人知道應(yīng)該怎么做,在 C# 里,所有人都被迫退化成最差的 Java 程序員 ;)
另外,Hejlsberg 還指出 C# 代碼里沒(méi)有被 catch 的異常,應(yīng)該可以用“靜態(tài)分析”檢查出來(lái)??梢钥闯鰜?lái),他并不理解這種靜態(tài)檢查是什么規(guī)模的問(wèn)題。要能用靜態(tài)分析發(fā)現(xiàn) C# 代碼里被忽略的異常,你必須進(jìn)行“全局分析”,也就是說(shuō)為了知道一個(gè)函數(shù)是否會(huì)拋出異常,你不能只看這個(gè)函數(shù)。你必須分析這個(gè)函數(shù)的代碼,它調(diào)用的代碼,它調(diào)用的代碼調(diào)用的代碼…… 所以你需要分析超乎想象的代碼量,而且很多時(shí)候你沒(méi)有源代碼。所以對(duì)于大型的項(xiàng)目,這顯然是不現(xiàn)實(shí)的。
相比之下,Java 要求你對(duì)異常進(jìn)行 throws 顯式聲明,實(shí)質(zhì)上把這個(gè)全局分析問(wèn)題分解成了一個(gè)個(gè)模塊化(modular)的小問(wèn)題。每個(gè)函數(shù)作者完成其中的一部分,調(diào)用它的人完成另外一部分。大家合力幫助編譯器,高效的完成靜態(tài)檢查,防止漏掉異常處理,避免不必要的 try-catch。實(shí)際上,像 Exceptional 一類(lèi)的 C# 靜態(tài)檢查工具,會(huì)要求你在注釋里寫(xiě)出可能拋出的異常,這樣它才能發(fā)現(xiàn)被忽略的異常。所以 Exceptional 其實(shí)重新發(fā)明了 Java 的 CE,只不過(guò) throws 聲明被寫(xiě)成了一個(gè)注釋而已。
說(shuō)到 C#,其實(shí)它還有另外一個(gè)特別討厭的設(shè)計(jì)錯(cuò)誤,引起了很多不必要的麻煩。感興趣的人可以看看我這篇文章:《可惡的 C# IDisposable 接口》。這個(gè)問(wèn)題浪費(fèi)了整個(gè)團(tuán)隊(duì)兩個(gè)月之久的時(shí)間。所以我覺(jué)得作為 C# 的設(shè)計(jì)者,Hejlsberg 的思維局限性相當(dāng)大。我們應(yīng)該小心的分析和論證這些人的言論,不應(yīng)該把他們作為權(quán)威而盲目接受,以至于讓一個(gè)優(yōu)秀的語(yǔ)言特性被誤解,不能進(jìn)入到新的語(yǔ)言里。
結(jié)論?
所以我對(duì) Kotlin 是什么“結(jié)論”呢?我沒(méi)有結(jié)論,這篇文章就像我所有的看法一樣,僅供參考。顯然 Kotlin 有的地方做得比 Java 好,所以它不會(huì)因?yàn)闆](méi)有 CE 而完全失去意義。我不想打擊人們對(duì)新事物的興趣,我甚至鼓勵(lì)有時(shí)間的人去試試看。
我知道很多人希望我給他們一個(gè)結(jié)論,到底是用一個(gè)語(yǔ)言,還是不用它,這樣他們就不用糾結(jié)了,然而我并不想給出一個(gè)結(jié)論。一來(lái)是因?yàn)槲也幌胱屓烁杏X(jué)我在“控制”他們,如何看待一個(gè)東西是他們的自由,是否采用一個(gè)東西是他們自己的決定。二來(lái)是因?yàn)槲疫€沒(méi)有時(shí)間和機(jī)會(huì),去用 Kotlin 來(lái)做實(shí)際的項(xiàng)目。另外,我早就厭倦了試用新的語(yǔ)言,如果一個(gè)大眾化的語(yǔ)言沒(méi)有特別討厭,不可原諒的設(shè)計(jì)失誤,我是不會(huì)輕易換用新語(yǔ)言的。我寧愿讓其他人做我的小白鼠,去試用這些新語(yǔ)言。到后來(lái)我有空了,再去看看他們的成功或者失敗經(jīng)歷 :P
所以對(duì)我個(gè)人而言,我至少現(xiàn)在不會(huì)去用 Kotlin,但我并不想讓其他人也跟我一樣。因?yàn)?Java,C++ 和 C 已經(jīng)能滿(mǎn)足我的需求,它們相當(dāng)穩(wěn)定,而且我對(duì)它們已經(jīng)很熟悉,所以我為什么要花精力去學(xué)一個(gè)新的語(yǔ)言,去折騰不成熟的工具,放下我真正感興趣的算法和數(shù)據(jù)結(jié)構(gòu)等問(wèn)題呢?實(shí)際上不管我用什么語(yǔ)言寫(xiě)代碼,我的頭腦里都在用同一個(gè)語(yǔ)言構(gòu)造程序。我寫(xiě)代碼的過(guò)程,只不過(guò)是在為我腦子里的“萬(wàn)能語(yǔ)言”找到對(duì)應(yīng)的表達(dá)方式而已。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容