Kotlin - 解构声明

2,609 阅读1分钟

kotlin可以把一个对象拆解为多个变量,这种操作叫做 解构声明

定义一个简单的 数据类

data class Person(var name: String, var age: Int)

fun main() {
    val person = Person("zhangsan", 1)
    println("-> ${person.name}")
    println("-> ${person.age}")

    val (name, age) = person
    println("-> $name")
    println("-> $age")
}

// 输出
-> zhangsan
-> 1
-> zhangsan
-> 1

name、age变量分别输出了对应的属性值,大大简化了我们的操作。

数据类之所以可以使用解构声明,是因为数据类比较特殊,编译器默认为它声明了以下函数:

@NotNull
public final String component1() {
   return this.name;
}
public final int component2() {
   return this.age;
}

为 name、age 赋值,相当于分别调用了对象的 component1component2 方法,这是解构声明的核心原理。

自定义解构声明

普通的类不具备解构声明的功能,我们可以手动声明 componentN() 方法来实现解构,需要 operator 修饰符:

class Book(var title: String, var price: Float) {
    operator fun component1(): String = title
    operator fun component2(): Float = price
}

fun main() {
    val book = Book("平凡的世界", 19.9f)
    println("-> ${book.title}")
    println("-> ${book.price}")

    val (title, price) = book
    println("-> $title")
    println("-> $price")
}

// 输出
-> 平凡的世界
-> 19.9
-> 平凡的世界
-> 19.9

数组、集合的解构声明

Kotlin中数组、list、map默认支持解构声明

fun main() {
    val array = arrayOf(1, 2, 3)
    val (a, b, c) = array
    println("-> a: $a b: $b c: $c")

    val list = listOf(1, 2, 3)
    val (d, e, f) = list
    println("-> d: $d e: $e f: $f")

    val map = mapOf("key1" to 1, "key2" to 2, "key3" to 3)
    for ((key, value) in map) {
        println("-> $key : $value")
    }
}

// 输出
-> a: 1 b: 2 c: 3
-> d: 1 e: 2 f: 3
-> key1 : 1
-> key2 : 2
-> key3 : 3

Lambda表达式中的解构声明

我们可以对Lambda表达式中的参数进行解构,首先这个参数要具备可以解构的条件:

fun main() {
    val book = Book("gone with the wind", 10.0f)
    showBookInfo(book) { (name, price) ->
        println("-> name: $name")
        println("-> price: $price")
    }
}

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