本文由 Prefert 發表在 ScalaCool 團隊部落格。
在今年的 Google I/O 大會上,Google 宣佈在 Android 上為 Kotlin 提供一等支援(轉為正房)。
在 Andorid 開發的圈子中,這無疑掀起了軒然大浪。對部分人來說,也許這是第一次聽到 Kotlin 。事實上,在 2011 年 7 月,JetBrains 就推出 Kotlin 專案,直到去年 2 月 Kotlin v1.0 才正式釋出。
本系列文章「Dive Into Kotlin」將會對 Kotlin 進行較為系統的介紹,大致分為四個章節:
1. 熱身 —— Kotlin 基本特性
2. 下水 —— Kotlin 與函式式
3. 潛入 —— Kotlin 核心
4. 遨遊 —— kotlin 與 Android 實戰
本文將簡單介紹 Kotlin 的生態和部分語言功能,目錄如下:
- Kotlin 是一門怎麼樣的語言
- 強大的生態圈
- 基本特徵
Kotlin 是一門怎麼樣的語言?
Kotlin 是一種在 JVM 上執行的靜態型別程式語言,可以編譯成 Java 位元組碼,也可以編譯成 JavaScript,方便在沒有 JVM 的裝置上執行。
Kotlin 核心的目標
-
簡約:幫你減少實現同一個功能的程式碼量。
-
易懂:讓你的程式碼更容易閱讀,同時易於理解。
-
安全:移除了你可能會犯錯誤的功能。
-
通用:基於 JVM 和 JavaScript,你可以在很多地方執行。
-
互操作性: Kotlin 和 Java 可以相互呼叫,同時 Jetbrains 的目標是讓他們 100% 相容。
對比 Java,Kotlin 或許顯得有點年輕,但這並不代表它的生態圈不夠穩定。
強大的生態圈
Kotlin 編譯為 JVM 位元組碼或 JavaScript
它可以吸引所有使用垃圾回收機制語言的程式設計師,包括 Java,Scala,Go,Python, Ruby 和 JavaScript。
kotlin 產自工業,而不是學術界。
它解決了程式設計師目前所面臨的一些問題。舉個例子:型別系統可以幫助你避免空指標異常。當我們在使用一些 API 或者大型庫時判斷是否為 null,往往沒有什麼實際作用。
Kotlin 完美相容 Java
在 Idea 中,你可以一鍵實現 Java 與 Kotlin 的轉換。也就是說, Kotlin 寫的專案中可以使用所有現有的 Java 框架和庫,甚至是依賴於註解的高階框架,並且它整合了 Maven,Gradle 和其他構建工具——幫助我們實現無縫的互操作。
Kotlin 相對入門簡單
所以正如大家所說的那樣,Kotlin 是一門十分友好的語言,你甚至可以花幾個小時閱讀下相關書籍就能入門。它的語法簡潔直觀,也許大多時候看起來比較像 Scala,實際上簡單了很多。這種語言很好地平衡了簡潔和可讀性。
不施加執行時間的開銷
標準庫是比較小的:主要是對 Java 標準庫的重點擴充套件。大量使用編譯時內聯(compile-time inlining)就意味著像 map
、 filter
、 reduce
這樣的語法編譯起來與命令式的相似。
Android擴充套件庫
Anko 與 kovenant 讓 Kotlin 在 Android 的開發中更加方便,如果你看過這兩個庫,一定也為之青睞。
除 Android 外,其實企業級別的 Java 專案也可以考慮使用 Kotlin:
-
它有一個成熟的公司強大的商業支援,JetBrains 致力於該專案的發展,擁有一支高效的團隊和穩定的商業模式。在較長的時間內,你都不用擔心 Kotlin 被拋棄。
-
Kotlin 的風險很低:可以由一兩個成員嘗試在某個功能塊使用,但並不會影響其他模組:Kotlin 類可以匯出一個與常規 Java 程式碼看起來相同的 Java API。
-
Java 6 廢土中的一線希望:如果升級 JVM 對於你們的成本很高,你可以使用 Kotlin,它是「加強版的 Java 6」。
看完生態圈,來看看最吸引我們的語言功能部分。
特徵
屬性前置
Java Bean 中總是出現一些重複工作量的程式碼:
public class Customer{
String name;
int age;
public Customer(String name, int age){
this.name=name;
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public setName(String name){
this.name=name;
}
public setAge(int age){
this.age=age;
}
}
複製程式碼
在 Java 物件中,建構函式和屬性的 Getter
、Setter
函式在每個Bean類中都會出現,看起來非常冗餘。
但是使用 Kotlin,程式碼是這樣的:
data class Customer(val name:String, val age:Int)
複製程式碼
Kotlin 將Getter
、Setter
等函式省略,讓我們更加關注屬性。
函數語言程式設計是變革的關鍵
如果你是一名 「FP」 (Functional Programming) 愛好者,你肯定知道 Scala 這門語言。而 Kotlin 的設計初衷就是提供 Scala 裡的很多特性,但不被編譯時間束縛。
網上對函數語言程式設計的介紹,大多數對初學者都是不夠友好的,下面是一種比較簡潔的概括:
函式程式設計以基於數學的函式構成,實現一個功能時傾向於實現的目標,而不是實現目標的方式。
也就是說,函數語言程式設計處理的是不可變的資料,即不會改變變數的值。它所做的只是 Receive(接收)-> Compute(計算)-> Return(返回) ,而不改變它接收到的值,或者引起「副作用」。
Kotlin 重新定義了函式的寫法
- 簡化函式過載。
- 命名引數不遵循順序:命名引數允許完全控制什麼值被傳遞給變數,並在與布林處理,舉個例子:
// Java
void check(boolean isAlpha, boolean isNum){
// do something
}
check(true, false); // 函式呼叫
// Kotlin
fun check(isAlpha:Boolean, isNum:Boolean = false) {
// do something
}
check(true)// 1
check(true,true)// 2
check(isAlpha = true, isNum = false) // 3
check(isNum = false, isAlpha = true) // 4
複製程式碼
其中1、3、4實際效果一致。
函式可讀性
- 單行表示式是提高程式碼可讀性的第一步。
// Java
int sum (int x, int y){ // 必須宣告返回型別
x = x + y; // x的值被改變,帶來副作用
return x;
}
// kotlin
fun sum(x: Int, y: Int) = x + y // 完美
複製程式碼
在 Android 開發時,我們應該都會對檢視的 onClick
事件感到煩躁。
// Java
view.setOnClickListener(new View.OnClickKistener() {
@ Override
public void onClick(View v){
System.out.println("sad");
}
});
複製程式碼
在 kotlin 中,這也得到簡化:
view.onClick {
println("nice !!")
}
複製程式碼
型別安全
在 Android 開發中,出現 NullPointerException
已經可以說是家常便飯了。但如果在執行的時候出現這個異常導致程式崩潰,對使用者體驗造成的損失是巨大的。
Kotlin 能很好的避免這個問題:
- 指定 null
// Java
String text1 = null // NE
// Kotlin
var text1: String = "Kotlin"// 正常
var text2: String = null // NE
var text3: String ?= null // 正常
複製程式碼
Kotlin 中只有加了 ?
才允許為 null。
- 檢查 null
Kotlin 可以通過
?
確保安全呼叫:
// Java
if(a != null){
int x = a.length();
}
// Kotlin
val x = a?.length // 僅當 a 不為 null 時才能通過編譯
複製程式碼
- 為 null 時預設值
val x = b?.length ?: 0 // 如果 b 為 null,那他的 length 就為0
val x = b?.length ?: throw NullPointerException()
val x = b!!.length
複製程式碼
Lambda 優化
Lambda 表示式增加了 Kotlin 的簡潔功能,從而也讓程式碼更容易理解。(Java 6 不支援 lambda )
val sum = {x: Int, y: Int -> x + y} // 型別:(Int, Int) -> Int
val result = sum(2, 7)// result == 9
複製程式碼
條件判斷更優雅
kotlin 中 when
同樣能帶給你驚喜,你可以用它簡化 if..else
或 switch
:
// Java
if(x == 1) println("x is 1");
else if(x == 2) println("x is 2");
else if(x == 3 || x == 4) println("x is 3 or 4");
else if(x >= 5 || x <= 10) println("x is 5, 6, 7, 8, 9, or 10");
else println("x is out of range");
// Kotlin
when (x) {
1 -> print("x is 1")
2 -> print("x is 2")
3, 4 -> print("x is 3 or 4")
in 5..10 -> print("x is 5, 6, 7, 8, 9, or 10")
else -> print("x is out of range")
}
複製程式碼
當然除了以上這些,Kotlin 還有許多令人驚喜的特性,將會在後續的文章中詳細介紹,敬請期待。