簡單即是美

在之前的三篇文章中,我們已經瞭解了一下的內容:

  1. 如何在項目中使用 Kotlin,Kotlin 的空安全
  2. 集合的相關操作,擴展函數以及 Lambda 表達式等高級特性
  3. for 與集合遍歷,強大的 if 、when 表達式,可以用來做單例模式的伴生對象

數據類

你是否已經厭煩了一個項目中大量的 POJO ?是的,雖然我們有大量的插件來幫助我們簡化這些創建過程,但是滿天的 gettersetter 還有那些 equals()/hashCode() 大量機械的、重複的方法。

Kotlin 爲我們提供了更強大數據類,如下所示:

data class User(var name: String="", var age:Int = 0){
    var nickname:String = ""
}

使用 data 關鍵字來告知系統這是一個數據類,其主構造函數需要至少有一個參數,如果生成的類需要含有一個無參的構造函數,則所有的屬性必須指定默認值。

請注意,對於那些自動生成的函數,編譯器只使用在主構造函數內部定義的屬性。如需在生成的實現中排出一個屬性,請將其聲明在類體中。

自動生成的函數只是用主構造函數定義的屬性

複製一個數據類

複製數據類的兩個方式

當我們使用 copy 函數時,系統會找到該類的主構造函數的簽名,此時我們可以按順序填入參數(無需完全填寫,會從第一位開始自動匹配),還可以採用類似 Python 的方式 參數名 = 值的方式來修改我們需要的參數值。

解構聲明

這四個字對於 Android + Java 開發者是挺陌生的,大家可以點擊到 Kotlin 中文站查看詳細的定義,下面我們通過代碼來了解一下他的用法,首先我們來看一張熟悉的圖:
for 循環遍歷 Map 集合

注意這裏的 (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")
        }
    }

標準庫提供了 PairTriple 這兩個類,前者表示兩個參數,後者表示三個參數。儘管在很多情況下命名數據類是更好的設計選擇, 因爲它們通過爲屬性提供有意義的名稱使代碼更具可讀性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章