在之前的三篇文章中,我們已經瞭解了一下的內容:
- 如何在項目中使用 Kotlin,Kotlin 的空安全
- 集合的相關操作,擴展函數以及 Lambda 表達式等高級特性
- for 與集合遍歷,強大的 if 、when 表達式,可以用來做單例模式的伴生對象
數據類
你是否已經厭煩了一個項目中大量的 POJO ?是的,雖然我們有大量的插件來幫助我們簡化這些創建過程,但是滿天的 getter
與 setter
還有那些 equals()/hashCode()
大量機械的、重複的方法。
Kotlin 爲我們提供了更強大數據類,如下所示:
data class User(var name: String="", var age:Int = 0){
var nickname:String = ""
}
使用 data 關鍵字來告知系統這是一個數據類,其主構造函數需要至少有一個參數,如果生成的類需要含有一個無參的構造函數,則所有的屬性必須指定默認值。
請注意,對於那些自動生成的函數,編譯器只使用在主構造函數內部定義的屬性。如需在生成的實現中排出一個屬性,請將其聲明在類體中。
複製一個數據類
當我們使用 copy
函數時,系統會找到該類的主構造函數的簽名,此時我們可以按順序填入參數(無需完全填寫,會從第一位開始自動匹配),還可以採用類似 Python 的方式 參數名 = 值
的方式來修改我們需要的參數值。
解構聲明
這四個字對於 Android + Java 開發者是挺陌生的,大家可以點擊到 Kotlin 中文站查看詳細的定義,下面我們通過代碼來了解一下他的用法,首先我們來看一張熟悉的圖:
注意這裏的 (k,v)
這就是一個解構聲明,標準庫已經幫我們實現瞭解構聲明,另外數據類也已經實現了主構造函數包含參數的解構聲明。
比如剛剛我們創建的 User 類,我們可以通過如下的方式來獲取其中指定的值:
var (name,age) = c
var (_,aged) = d //用下劃線佔位不需要的參數
var aged1 = d.component2() //直接使用 componentN 函數來獲取對應的值
println("c's name = $name c's age = $age")
println("don't need d's name, d's age = $aged")
println("other way to get d's age is $aged1")
我們可以任意的在類中進行解構聲明,比如我們可以使用解構聲明來擴展剛剛我們定義的 User 類:
data class User(var name: String="", var age:Int = 0){
var nickname:String = ""
operator fun component3() = nickname
}
需要注意的是,數據類默認爲我們實現了主構造函數的參數解構聲明,所以我們的解構聲明只能接着主構造函數的序號往後使用
在 Lambda 表達式中使用解構聲明
當這個類進行了解構聲明時,我們可以直接在 Lambda 表達式中使用其解構,如下:
c.let { (a,b,c) ->
println("c's name = $a , c's age = $b , c's nickname = $c")
}
請注意解構聲明對於 Lambda 表達式而言是一個參數:
{ a //-> …… } // 一個參數
{ a, b //-> …… } // 兩個參數
{ (a, b) //-> …… } // 一個解構對
{ (a, b), c //-> …… } // 一個解構對以及其他參數
在函數中返回數個參數
有的時候我們經常會希望一個函數能返給我們多個結果,例如曾經我做過一個小功能:傳入 PM2.5 的值,返回當前 PM2.5 嚴重程度的介紹以及需要顯示的顏色代碼。當時我採用的做法是返回一個 Map,然後再需要的地方在使用固定的 key 將值提取出來,這一點也不優雅。
但是在 Kotlin 裏 你可以這樣做:
fun getPM25DescAndColor(pm25: Int):Pair<String,String> {
return when (pm25) {
in 0..50 -> Pair("優秀","#009900")
in 51..100 -> Pair("良好","#FFCC33")
in 101..150 -> Pair("輕度","#FF9900")
in 151..200 -> Pair("中度","#FF3300")
in 201..300 -> Pair("重度","#9900FF")
else -> Pair("嚴重","#663300")
}
}
標準庫提供了 Pair
和 Triple
這兩個類,前者表示兩個參數,後者表示三個參數。儘管在很多情況下命名數據類是更好的設計選擇, 因爲它們通過爲屬性提供有意義的名稱使代碼更具可讀性。