一、什麼是解構聲明
在 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)
。