一、什么是解构声明
在 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)
。