Kotlin笔记10- Destructuring Declarations 解构声明

参考官网对于解构声明的介绍:http://kotlinlang.org/docs/reference/multi-declarations.html

借助于解构声明的语法,可以很方便的将一个对象解构成几个变量,比如:

val (name, age) = person
println(name)
println(age)

解构声明会创建相应个数的变量,编译为以下代码:

val name = person.component1()
val age = person.component2()

component1()和component2()函数是Kotlin中广泛使用的约定原则的另一个例子(参见+和*,for-loops等运算符)。 只要可以在其上调用所需数量的组件函数,任何东西都可以在解构声明的右侧。 当然,可以有component3()和component4()等等。

⚠️注意,在使用解构声明时,相应的componentN()函数要用operator修饰符来修饰。

示例1. 从一个函数返回两个值

data class Result(val result: Int, val status: Status)
fun function(...): Result {
    // computations
    
    return Result(result, status)
}

// Now, to use this function:
val (result, status) = function(...)

数据类data classes会自动生成componentN()函数

⚠️注意:我们也可以使用标准的二元组类Pair,然后使得function()函数返回Pair<Int, Status>类型,但是通常建议使用自己命名好的类,这样会让代码更具有可读性。

示例2. 在遍历Map时,使用解构声明

遍历一个map最完美的方式如下:

for ((key, value) in map) {
   // do something with the key and the value
}

要能够这样来遍历,要做到以下两点:

1. 通过提供iterator()函数将映射map显示为值序列;
2. 通过提供函数component1()和component2()将每个元素作为一对呈现。
而事实上,标准库提供了这样的扩展:

operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = entrySet().iterator()
operator fun <K, V> Map.Entry<K, V>.component1() = getKey()
operator fun <K, V> Map.Entry<K, V>.component2() = getValue()

通过以上标准库提供的操作符函数,我们可以在遍历map的for循环中很方便的使用解构声明,以及在遍历数据类的集合中来使用。

对未使用的变量使用下划线(1.1版本开始)

如果对于解构声明中的一个变量,如果不需要使用,那么可以使用下划线来替代其名称,如:

val (_, status) = getResult()

像这样掠过某个变量名时,该变量对应的运算符函数componentN不会本调用。

在lambda表达式中使用解构声明

您可以对lambda参数使用解构声明语法。 如果lambda具有Pair类型的参数(或Map.Entry,或具有相应componentN函数的任何其他类型),则可以通过将它们放在括号中来引入几个新参数而不是一个:

map.mapValues { entry -> "${entry.value}!" }
map.mapValues { (key, value) -> "$value!" }

在lambda表达式中,声明两个参数和声明一个解构的组合是不一样的

{ a -> ... } // one parameter
{ a, b -> ... } // two parameters
{ (a, b) -> ... } // a destructured pair
{ (a, b), c -> ... } // a destructured pair and another parameter

在lambda表达式的参数列表中,对于未使用的解构后的参数,,可以使用下划线替代其名称,如:

map.mapValues { (_, value) -> "$value!" }

在lambda表达式的参数列表中,可以声明解构的变量的整体类型,也可以针对某个解构后的变量,指定其类型,如:

map.mapValues { (_, value): Map.Entry<Int, String> -> "$value!" }

map.mapValues { (_, value: String) -> "$value!" }

猜你喜欢

转载自blog.csdn.net/unicorn97/article/details/81586581