Categories
程式開發

Kotlin核心編程:Kotlin,改良的 Java


編者按:本文節選自華章科技出版的 《Kotlin核心編程》一書中的部分章節。

2010年,JetBrains產生創造Kotlin的想法。關於大名鼎鼎的JetBrains,想必在業內是人盡皆知,知名的IntelliJ IDEA就是他們的產品之一。擁有為各種語言構建開發工具經驗的JetBrains,自然是對編程語言設計領域最熟悉的一群人。當時,一方面他們看到了C#在.NET平台上大放異彩;另一方面,Java相比新語言在某種程度上的滯後,讓他們意識到改良Java這門主流語言的必要性。

JetBrains團隊設計Kotlin所要面臨的第一個問題,就是必須兼容他們所擁有的數百萬行Java代碼庫,這也代表了Kotlin基於整個Java社區所承載的使命之一,即需要與現有的Java代碼完全兼容。這個背景也決定了Kotlin的核心目標——為Java程序員提供一門更好的編程語言。

Kotlin的實用主義

Kotlin常常被認為是一門近似於Scala的語言。的確,它們的誕生都源於對Java語言的改良,同時都在面向對象和函數式之間建立起了多範式的橋樑。不可否認的是,Kotlin確實從Scala身上借鑒了許多,就連它的創作團隊也表示過:“如果你用Scala感到很開心,那麼你並不需要Kotlin。”

然而,Kotlin與Scala的設計哲學又十分不同。 Kotlin並沒有像Scala那樣熱衷於編程語言本身的研究和探索。相反,它在解放Java的同時,又在語言特性的選擇上表現得相當克制。

我們說過,Scala旨在成為一門程序員夢想中的語言,它包含了所有你想擁有的語言特性。而Kotlin更加立足現實,它現階段仍沒有宏,也拒絕了很多所謂的高級函數式語言特性。但它在Java 的基礎上發展出很多改善生產力的語言特性,如數據類、when表達式(一定程度上的模式匹配)、擴展函數(和屬性)、可空類型等,而且它似乎偏好語法糖,比如Smart Casts,因為這可以讓編程人員的工程開髮變得更加容易。

可以看出,Kotlin的自我定位非常清晰,它的目標就是在計算機應用領域成為一門實用且高效的編程語言。如果說Scala的設計理念是more than Java(不僅僅是Java),那麼Kotlin才是一門真正意義上的better Java(更好的Java)。

更好的Java

如果你用Kotlin開發過業務,很快就會意識到它相較於Java的語法更加簡潔、高效。比如Kotlin做了這些改良:

  • 在很大程度上實現了類型推導,而Java在SE 10才支持了局部變量的推導。
  • 放棄了static關鍵字,但又引入了object,可以直接用它來聲明一個單例。而作為比較,Java則必須依靠構建所謂的“單例模式”才能等效表達。
  • 引入了一些在Java中沒有的“特殊類”,比如Data Classes(數據類)、Sealed Classes(密封類),我們可以構建更深程度上的代數數據類型,結合when表達式來使用。

但可能你會問,以上Kotlin的特性,Scala也有,能否可以說前者只是後者的一個子集呢?這種表述其實是不恰當的。其實,Kotlin在致力於成為更好的Java的道路上,不僅僅依靠這些新增的語言特性,它在兼容Java方面做了大量的工作,比Scala走得更遠。

首先,從語言命名上就可以看出Kotlin在嚴格遵循Java的傳統,它們都採用了島嶼的名字。

Java的名字來源於印度尼西亞瓜哇島的英文名稱,而Kotlin是俄羅斯聖彼得堡附近的一個島嶼的名字。

其次,雖然都是兼容Java,Scala(最近的幾個版本)必須要求Java 8,而Kotlin則可以與Java 6一起工作,這也是後者在Android上更加流行的原因之一。

另外,Kotlin並沒有像Scala那樣在語法的探索上表現得“隨心所欲”,Java程序員在學習Kotlin新語法特性的同時,依舊可以保留更多原有的習慣。舉個例子,在Scala中,一切皆有類型。所以在大部分時間裡,我們都用等號來定義一個Scala的函數。函數體最後一個表達式的值就是這個函數的返回類型。

def foo(x: Int) = {
    val y = x + 2
    x + y
}

沒錯,Scala捨棄了return關鍵字。在Kotlin中,它也引入了使用單行表達式來定義函數的語法,不需要用return來返回結果值。

fun foo(x: Int) = x * 2 + 2

然而,大部分情況下,我們還是可以採用類似Java的方式來定義一個函數,如:

fun foo(x: Int): Int {
    val y = x * 2
    return y + 2
}

由於Kotlin比Scala更加兼容Java的生態和語法,Java程序員可以更加容易地掌握它。同時,Kotlin非常注重語法的簡潔表達。如果你了解Scala中的implicit,可能曾被這個Scala的語法驚嚇到,因為它非常強大。然而,正如我們提到的,“簡單靈活”的另一面意味著抽象和晦澀。 Kotlin注重的是工程的實用性,所以它創造了擴展的語法,雖然相比implicit在功能上有損失,但顯得更加具體直觀,且依舊非常強大,可滿足日常開發中絕大多數的需求。值得一提的是,Android則依靠這個Java所沒有的特性,推出了擴展庫android-ktx,我們在第7章將專門介紹這種強大的特性。

此外,Kotlin還新增了一些Java、Scala中沒有的語法糖。如果你從事Android開發,那麼肯定少不了在工程中寫過如下的Java代碼:

if(parentView instanceof ViewGroup){
    ((ViewGroup) parentView).addView(childView);
}

為了類型安全,我們不得不寫兩遍ViewGroup。然而在Kotlin中我們卻可以直接這麼寫:

if(parentView is ViewGroup){
    parentView.addView(childView)
}

這依靠的是Kotlin中的Smart Casts特性。我們不評價這種語法糖是好是壞,但它可以在一定程度上改善我們在工程開發中的體驗。

總體而言,Kotlin旨在成為一門提升Java生產力的更好的編程語言,它擁有簡潔的表達能力、強大的工具支持,同時至今仍然保持著非常快速的編譯能力。相較而言,用Scala開發則常常受到編譯過慢帶來的困擾。

強大的生態

現在,我們已經了解了Kotlin整體的設計哲學,以及它相較Java、Scala的魅力所在。當然,本章似乎並沒有涉及任何語法細節,我們會在後續的內容中深入介紹Kotlin的語言特性,並且探索它具體的高級應用。

關於Kotlin,還有一個問題需要解答:我們究竟可以用它來做什麼?大概率上你是因為Kotlin成為Android官方支持語言的新聞而知曉它的。事實上,Kotlin不僅支持Android,它還是一門通用語言,如果用一句話來總結,那就是“Targeting JVM / JavaScript and Native”。現階段,我們至少可以用Kotlin做以下的事情。

(1)Android開發

我們不僅可以用Kotlin調用現成的Java庫,而且還有Google提供的Kotlin擴展庫。 Kotlin的語法非常適合Android工程開發,例如我們提到過的Smart Casts。用它還可以改善findViewById的語法調用。

(2)服務端開發

這是JVM語言最大的一個應用領域,自然也是Kotlin發揮的舞台。在Android支持Kotlin之後,Spring Framework 5也對它敞開了懷抱。基於Kotlin更自然的函數式特性,用Spring進行Web開發會在某些方面擁有比Java更好的開發體驗。

(3)前端開發

Kotlin還有兩個強大的特性:dynamic類型及類型安全的構建器。前者實現其與JavaScript互通,後者可以幫助開發者構建可靠的HTML頁面。你可以嘗試使用Kotlin來構建UI。

(4)原生環境開發

因為Kotlin Native這個項目,Kotlin終於告別了Java,離開了JVM,直接編譯成機器碼供系統環境運行。雖然Kotlin Native尚處於早期階段,但後續的發展非常值得期待。如果你家裡有一個樹莓派,不妨可以用它來試一試。

如你所見,Kotlin還是一門非常開放、具有強大生態的編程語言。如果說與Java兼容能讓它運行在所有支持Java的地方,那麼它的革命創新使得它超越了Java,進入了更加廣闊的世界。

圖書簡介https://item.jd.com/12519581.html?dist=jd

Kotlin核心編程:Kotlin,改良的 Java 1

相關閱讀

Scala複合但不復雜,簡單卻不容易