為啥 Kotlin 是我下一個要掌握的語言
Kotlin 是 JetBrains 的一門新的編程語言,這個公司開發了世界上最好用的 IDE。經過一段時間的研究,我決定將其作為今后5到10年的時間里用到的一門編程語言。
我 很喜歡 Kotlin,它肯定會成為一個成功的項目。有人看到我在我的開源項目里用了這門語言,就讓我說點什么,那么在這篇文章里我就來說一說為什么我覺得 Kotlin 好了。接下來我還會說一下,如果你現在就開始用這門語言,會遇到的問題。最后我會告訴你 Kotlin需要用到 JVM,這個你需要考慮一下(因為你也許正在用 Go 或者 Node),但是我認為這不是問題。
請注意 Kotlin 目前還是 beta 版:1.0正式版有望在2015年底發布,會提供穩定的語言特性和標準庫。
Kotlin好在哪里
本文一開始似乎有點奇怪:通常鼓吹某個編程語言的文章一上來都會列出新語言都有哪些酷的特性。不過本文不是這樣,哪些我們稍后一些再聊。
我們先了解一下其他方面,因為針對開發人員評估編程語言,一個2013年的研究表名,編程語言的特性相對于語言的生態來說,重要程度相對要低一些,這也跟我的經驗相符。那么,下面就是我們需要先介紹的:
Kotlin 會編譯成 JVM 字節碼或者 JavaScript。它不需要新寫一個編程語言內核。Java 開發者肯定會很感興趣這門語言,不過對于其他所有使用帶有垃圾收集機制的語言的開發者來說,同樣值得關注,這些語言包括 Scala, Go, Python, Ruby 和 JavaScript。
Kotlin 源自產業界, 而非學院。它解決了當前程序設計所面臨的實際問題。例如,類型系統可以避免空指針異常的問題。
使用 Kotlin 不需要費用! 它是開源的, 但這不是我要說的,我要說的是它有一個高質量的,Java 到Kotlin 轉換工具,非常關注 Java 二進制的兼容性。你可以將一個 Java 工程全部轉換,一次只能轉換一個文件。甚至上百萬行的復雜程序。這就是我為什么使用 Kotlin 的原因,我期待所有的開發者都使用它。
上面已經顯示,Kotlin 程序可以使用已經存在的 Java 框架和類庫,甚至依籟注解處理的高級框架。互操作是無縫的,而且不需要包裝器和適配層。它可以集成Maven,Gradle或者其他的編譯系統。
它很容易上手,簡單地閱讀一下參考手冊幾個小時就可以學. 語法精益而直觀。Kotlin 有點像 Scala, 但它更簡單。語言平衡了簡潔和可讀性。
它沒有強制的編程哲學,像過度函數編程和面向對象風格。
它沒有運行時開銷, 標準庫小而緊湊,它主要包括 Java 標準庫的擴展。大量使用內聯編譯時間的功能性結構類似 map/filter/reduce 管道。
與 Anko 和 Kovenant 這樣的框架結合,輕量的資源意味著 Kotlin 開始在 Android 開發者中流行如果你在做 Android 開發,你很快就會獲得好的工作單位。你可以閱讀 a report written by a developer at Square,分享了他們使用 Kotlin 和 Android 的經驗,Kotlin 代碼就像 Java 一樣。完全支持調試,單元測試,分析等等。
除 Android 之外, 我認為 Kotlin 特別適合于處理商業 Java 業務。如果你在一個很大的公司整天面對著一個龐大的 Java 代碼庫,那么你應該趕快著手研究 Kotlin 了:
-
Kotlin 有著知名公司提供的強有力的商業支持。JetBrains 承諾:有一個高效出色的大型團隊正在致力于 Kotlin 的開發工作,而且對 Kotlin 運用穩定的商業模式,甚至正在將自己的部分旗艦產品轉換成用于使用 Kotlin。于是 Kotlin 不太可能會在短期內被拋棄。
-
采用 Kotlin 是低風險的:可以在你代碼庫的一小部分里,通過一兩個熱衷于此的團隊成員在不影響項目其他代碼的前提下進行試用。Kotlin 的類能夠導入一個 Java 的 API,使得這看起來就像正常的 Java 代碼
-
由于 Kotlin 專注于語法的可讀性,從而使得代碼的審查易于進行:即便不熟悉 Kotlin 語言的團隊成員也同樣可以完成.
-
Kotlin以Java 6 為目標,所以即使在部署新版本 JVM 遇到困難的情況,你也仍然能夠使用Kotlin。
今年的早些時候我曾向一家大型保險公司,瑞士再保公司(Swiss Re)的一個以 Java 和 .NET 作為架構的團隊展示過 Kotlin. 我以這樣的方式開始,用 Java 定義了一個類,這個類帶有一些字段,和 toString, equals, hassCode 諸如此類的方法等等。這大約用了 50 行代碼。當我將其轉化為 Kotlin 的時候(基本上是自動完成的),這個類縮小到了只剩一行代碼。然后我又演示了其他可以節省敲代碼時間的特性。看到這些他們都很激動,并將 Kotlin 視為他們項目的潛在競爭者。
我想 Kotlin 為商用 Java 開發提供了一個恰當的時機,所以盡管 Kotlin 可以免費使用,不過隨著商業版本 IDE 銷售額的增加,我預計 JetBrains 定會大賺一筆. 而這也將刺激他們依照廣大客戶的意愿來不斷提升自身的產品.
與此相比,那些從與現有IDE不相關的產品中得到資助的其他語言開發者們,他們則很少會因為用戶的需求與自身產品先入為主的理念不一致,就做出相應的調整。
功能特性
Kotlin 因其對生態系統上的關注而從海量新興編程語言中脫引而出: JetBrains 了解到生產力的來源不只是在于更方便的語法。
盡管如此,Kotlin 還是有許多有用的功能特性,它們讓編寫代碼的人樂在其中:
-
我們已經提起過 空指針安全 (這是可選的一項功能),它會讓編譯器系統性的將潛在的空指針標識為無效的。不想某些語言那樣,這并不會涉及到一個可選類型且因此是零開銷的 。其它的語言特性確保了它不會是不方便的。
-
精益的語法: 類型推斷在任何地方都能起作用,單行方法只用一行就行了,簡單的結構體或者JavaBean也可以用一行就能被聲明出來。 Real 屬性 會在幕后為 Java 互操作生成 getFoo/setFoo 方法。函數可以存在于類的外部。
-
異常是未經檢查的。
-
向一個類添加 data 注解會觸發樣板程序的自動生成,像是 equals, hashCode, toString, copy 方法還有對可變擴展的支持。無需構建器你就很方便的擁有了不可變的類。
-
而如果你確實需要構建復雜的結構,有一種靈巧的語言特性的組合能使得 構建器 條理清晰且類型安全(讀是可自動完成的)。如果你是使用的 Google Protocol Buffers 來存儲結構性的數據,那也會更加的容器。
-
對函數式編程的支持 使用了 零開銷的 lambda 以及在 Java 集合上做映射和折疊的能力。Kotlin 的類型系統能在集合上做可變和不可變視圖的區分。
-
擴展函數 讓你可以給類添加方法,而無需修改他們的源代碼。這在初次看起來像是一個用來避免 FooUtils 風格的類的語法糖。到后來你會發現這樣做讓你可以很容易的通過自動補全功能來發現新的方法,使你可以構建出強大的語言擴展并讓你可以將現有的 Java API 同 Kotlin 的特性集成。這些特性有 …
-
操作符重載。而這個確實不錯:這里沒有 Scala / Perl 風格的行搗亂了。操作符映射到特定的方法名稱,如此就能重載現有操作符的行為了(包括函數的調用), 但是你不能定義一個完全是新的操作符。這樣就達到了能力和可讀性之間的一個平衡。
-
Kotlin 并沒有宏或者其它方式來對語言進行重新定義,但是有一些小心設計出來的特性,使得那些庫表現得更像語言擴展,而不是對象的集合。
-
你會喜歡使用 fiber, actor, 和 Go風格的 channel 嗎? 一個叫做 Quasar 的庫為你涵蓋到了這些。
-
使用 Markdown 而不是 HTML 來制作你的 API 文檔。這使得編寫 JavaDoc 令人高興了許多。
-
更好的 generics。如果你在放入一個類型變量時,超類和擴展究竟有什么意義從未得到完全認真的處理, 別擔心:這不是你的問題。Java 的 generics 確實有點令人困惑。Kotlin 解決了這個問題。
-
派發 (轉發方法) 是自動的。
-
== 操作符真正做了你實際期望的事情。
-
你喜歡快速和方便的異步編程嗎? 你當然會喜歡的。
-
字符串插值“works like ${this.example}!”
-
函數參數可以被命名、可選而且類型可變。
-
許多許多其它的調整和改進。如果 Java 的有些東西讓你不爽的話,我感覺其中一半的不爽在 Kotlin 中都不會有。
現在就來試一下!
跟很多現代編程語言一樣,Kotlin 可以通過瀏覽器來進行實驗性的使用。不過跟其他語言不一樣的是,Kotlin 的實驗網站展現給你的是一個完全成熟的 IDE,包括響應很快的自動完成,實時的背景編譯,甚至還有在線的靜態分析!
來試試吧
繼續嘗試一下。然后回來我們繼續。
有啥問題不?
生活中沒有十全十美,Kotlin 也如此。這里是我試用這門編程語言時遇到的一些問題。
最大的問題是不成熟。Kotlin 是一個未到 1.0 版本的語言。 這意味著:
-
語言本身,ABI 和 標準庫會在每個發行版中發生變化。好消息是,這些變化往往都比較小,而且 Intellij 可以經常為你升級你的代碼。所以這沒有聽起來那么痛苦。
-
Java-to-Kotlin 轉換器 (J2K) 還未開發完成。它有時會胡亂的格式化并且會默默的刪除 Java 8 lambda 表達式(2015 年 10 月修改:用于 M13 版的轉換器目前已經可以正確的處理 Java 8 的特性)。而且它產生的代碼也不總是最佳的編寫方式。但是 JetBrains 公司正在為這個工具投入顯著的精力,而且這已經是我用過的同類產品之中最好的了。所以我并不太擔心這一點:它將很快的越來越完善。
-
你將遇到編譯器 bug。我的程序并不大,但我經常遇到應該編譯的代碼沒有被編譯,或者(更糟糕的情況)代碼被編譯成了錯誤的東西。診斷這些問題并不是太困難,但這會給我們帶來不好的體驗。
-
你將遇到內部 IDE 錯誤。 當發生這種情況時你會看到一個提示氣泡以及一個匯報給 JetBrains 公司的選項。IDE 不會關閉,大多數錯誤似乎沒有太大的問題。但無論如何,這是很煩人的。
-
文檔有時會參考未實現的特性(修改:在 M14 版本中我相信這已經不再是一個問題了)。
現在 JetBrains 公司正在專注于 1.0 版本的完善而不是添加新特性,我希望這些問題都已經得到解決。
我遇到的第二大的問題,就是有時候其與 Java 的交互有一些局限。
一個典型的 bug 就是 Java 的類型系統無法保證你不改變 map 中 key 的類型。按照常理來說,如果你這樣做將會導致編譯錯誤,比如說,使用錯誤類型的 key 來刪除元素。但是當 JDK 集合使用了泛型,其中有些重要的方法的參數是 Object 的話,編譯器就不會報錯。在 Intellij 中編寫 Java 代碼時這種情況可以被標記成黃色的靜態分析警告,但到目前為止 Kotlin 編輯器還沒有這種功能(某些時候)。因為 Kotlin 沒有定義任何自己的集合類庫,這將導致一些類型安全性方面的一些問題,我已經遇到過好幾次了。
另一個例子是,當調用或使用 Java 代碼時,Kotlin 的 null 的安全特性是被禁用的(可以使用注解來彌補)。因為做為 Kotlin 初學者你可能會寫很多調用 Java 類庫的代碼,但是這個功能沒有你希望的那么有用。這只能等到 Kotlin 占有量增長來改善了。JetBrains 公司已經在嘗試解決與 Java 交互時 null 的安全特性的問題了:他們的想法是好的,但是有時卻未能發現問題。他們想要這么做來修復 null 的安全特性與 Java 交互的問題。(修改:在 M13 版中他們使用 Java @NotNull 注解來解決)
另一方面,這也能讓你更流暢的使用 Java API,我認為這種折衷是值得的。但是需要多加注意。
其他需要考慮的問題:
-
社區比較小。雖然出色的與 Java 交互性意味著你并不真的需要 Kotlin 庫,不過有總比沒有強,然而目前并不多。
-
如果你喜歡通過看書來學習,你將不得不等到今年晚些時候, Manning 將會出版一本。在此之前并沒有任何網站或其他東西。
-
函數式編程(FP)的死忠可能會覺得類型系統缺乏類似 Scala 或 Haskell 中的一些高級的功能。如果你是比較在乎類型系統的人,Kotlin 可能并不適合你。
-
雖然它可以向下編譯成 JavaScript,但這種模式似乎與 JVM 后臺相比不太好用,你可能會遇到更多的問題,需要說明的是我也沒有使用它的經驗,這只是在逛論壇時我留下的印象(修改:為了更快的推出 Kotlin 1.0 版,JS 后臺已經是非優先的了,當在 JVM 上穩定之后 JetBrains 才會繼續做這項工作)。
-
沒有標準風格的指南,而且有時 Kotlin 會提供好幾種語法讓你選擇。不同程序員寫的 Kotlin 代碼可能看起來是不一樣的。這是對于 Go 語言的硬性強制風格來說的。(修改:在 M14 版本中去掉了一些語法的靈活性,所以操作者必須明確的標示。)
-
Kotlin 的編譯速度比 Java 稍微慢一點,而且 Intellij 編輯器更慢。但并不是很嚴重,而且二者都比 Scala 要快。
-
有一個 Kotlin 的 Eclipse 插件,但自然它的完善度要比 Intellij 支持的少得多。Kotlin 在你的團隊規定使用 Intellij 開發時才能工作在最佳狀態。
-
Kotlin 比 Java 更挑剔。它不會自動將整型轉換成長整型,你必須明確的顯式轉換。這是因為該語言更看重正確性,而且嘗試修復在“Java 解惑”一書中發現的一些著名的問題。JetBrains 公司聲稱他們修正了其中的一半。
-
因為 Kotlin 是基于 Java 6 的,它只包含該運行時具有的功能。雖然他可以在很多領域中趕上或超過 C#,但它缺乏還不是 Java 平臺的一部分的類似值類型的特性。
為什么你真的需要對 JVM 做一些考慮
最近一段時間我遇到了很多使用動態腳本語言(如JavaScript,Go)的創業公司。
我在比特幣工作的時候,使用動態語言是非常痛苦的事情。在這些工具里沒有安全性的類型導致了巨大的貨幣損失。Go 出錯少點,但是仍然在基礎的東西上體驗很差,比如說缺少好的調試工具,快速 GC,穩健的管理器還有可靠的分析工具。
過去15年或更長時間,Java 變得越愛越長,并且被過分使用--在很大程度上源于它的聲譽。企業級 Java 的類的名字類似于 PathVariableMapMethodArgumentResolver 那么長。很長一段時間,我不考慮 JVM,我確信這種環境不是給我設計的。
最終我因為要搞 Android 而不得不轉向 Java。結果發現已經變了樣。雖然 XML 比起我們根據潮流所做的預期來,仍舊更加頻繁的被派上用場,而基礎設施的能力已經非常令人印象深刻了。IntelliJ 比起 Eclipse 來要快很多也更加的直觀。Maven,盡管一開始的時候勢不可擋,結果卻是大量在其它構建/依賴管理系統中有的功能特性才是我想要的。較新的像 Ninja 和 Play 這些 web 框架從諸如 Ruby on Rails 這樣的項目那里學到了敏捷的方法。還有大量的庫。硬件已經變得更好了,JVM 也變得更有效率。諸如此類,不一而足。
一個比較大的,還并沒有真的發生改變的東西就是語言本身。Java 的代碼寫起來仍然是冗長而令人痛苦和乏味的。
如今有了 Kotlin,傳統中同 Java 生態系統有關的最后一個痛點也成了過去式。你可以編寫更具表達能力,而且甚至比一種腳本語言更簡潔的代碼,然而 bug 更少,性能也更好。你可用上所有這些很棒的工具:只要嘗試一下捆綁的 VisualVM 程序,來體味一下在這個生態系統中那些可以免費試用的東西,或者如果你愿意花些錢,就可以上 Chronon 時間旅行調試器 網站看看你可以得到些什么。
如果你喜歡 JavaScript,可以嘗試 Kotlin 的后端JS。或者在 Nashorn JS 引擎里運行你現有的代碼。
最后,如果你喜歡 GO 語言是因為它會生成獨立的程序,看看 javapackager 的工具。Kotlin 在本地為每個平臺創建了捆綁包,這意味著在 linux 上不需要 JRE 的依賴就可以獨立自主的獲取 DEBs(linux 的安裝包)或者壓縮包。當然,從部署的角度來看,它拆開之后不是單個文件,而是不難運作的單個目錄。
簡而言之:如果你之前因為 JVM 的生態不流行而忽略了它,你可以再看看 Kotlin 或者把握住它。
來自: http://developer.51cto.com/art/201601/503465.htm