Kotlin 解構聲明

一、什麼是解構聲明

在 Koltin 中可以把一個對象賦值給多個變量,這種操作叫做解構聲明(Destructuring declaration),先看個例子:

data class Book(var name: String, var price: Float)

fun main(args: Array<String>) {
    val (name, price) = Book("Kotlin入門", 66.6f)
    println(name)
    println(price)
}
// 輸出
Kotlin入門
66.6

我們定義了一個簡單的數據類,name、price變量分別輸出了對應的屬性值,大大簡化了我們的操作,神奇吧!

數據類之所以可以使用解構聲明,是由於數據類比較特殊,編譯器默認爲它聲明瞭類似的函數:

operator fun component1(): String {
        return name
    }

    operator fun component2(): Float {
        return price
    }

爲 name、price變量賦值相當於分別調用了 Book 對象的component1()component2()函數,這也是解構的核心原理。

二、自定義解構聲明

對於一個普通的類自然不具備解構聲明的功能,但我們可以手動聲明類似operator fun component1()的方法,來實現解構的功能,例如我們去掉 Book 類的data修飾符,這樣Book就是一個普通的類了,然後聲明component1()component2()方法,注意需要operator修飾符:

class Book(var name: String, var price: Float) {
    operator fun component1(): String {
        return name
    }

    operator fun component2(): Float {
        return price
    }
}

fun main(args: Array<String>) {
    val (name, price) = Book("Kotlin入門", 66.6f)
    println(name)
    println(price)
}

這樣就爲一個普通類實現瞭解構聲明的功能。

類似的,如果需要一個函數可以返回多個值,也可以考慮使用解構聲明:

data class Book(var name: String, var price: Float)

fun getBookInfo(): Book {
    return Book("Kotlin入門", 66.6f)
}

fun main(args: Array<String>) {
    val (name, price) = getBookInfo()
}

瞭解了這個原理,要讓一個類可以實現解構聲明的功能也就很簡單了。

三、數組、集合的解構聲明

Kotlin 中數組,list、map系列集合默認也支持解構聲明的功能,例如:

fun main(args: Array<String>) {
    val array = arrayOf(1, 2, 3)
    val (a1, a2, a3) = array
    
    val list = listOf(1, 2, 3)
    val (b1, b2, b3) = list
    
    val map = mapOf("key1" to 1, "key2" to 2, "key3" to 3)
    for ((key, value) in map) {
        println("$key-$value")
    }
}

四、忽略不需要的解構

如果在解構聲明中不需要某個變量,那麼可以用下劃線_取代其名稱,這樣也就不會調用相應的componentN()操作符函數:

val (_, price) = Book("Kotlin入門", 66.6f)

五、 Lambda 表達式中的解構聲明

同樣的我們可以對 Lambda 表達式中的參數進行解構聲明,當然這個參數要具備可以解構的條件,這部分內容在Kotlin 高階函數與 Lambda 表達式中已經提到過了,當時如果不瞭解解構聲明的話可能不太好理解,這裏再舉個例子加深下印象:

data class Book(var name: String, var price: Float)

fun showBookInfo(book: Book, block: (Book) -> Unit) {
    book.run(block)
}

fun main(args: Array<String>) {
    val book = Book("Kotlin入門", 66.6f)

    showBookInfo(book) { (name, price) ->
        println("書名:$name")
        println("價格:$price")
    }
}

即我們將默認的Book類型的it參數解構成了(name, price)

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