Android开发Android开发经验谈Android技术知识

Kotlin 解构声明

2018-12-20  本文已影响12人  SheHuan

一、什么是解构声明

在 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)

上一篇 下一篇

猜你喜欢

热点阅读