Kotlin 中文文档 v2.0.10 Help

解构声明

有时,将对象 解构 成多个变量能更方便我们的使用,例如:

val (name, age) = person

这种语法称为 解构声明 。解构声明一次能创建多个变量。 现在你已经声明了两个新变量: nameage ,并且可以独立使用它们:

println(name) println(age)

解构声明会被编译成以下代码:

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

component1()component2() 函数是 约定原则 的另一个例子,在 Kotlin 中广泛使用 (参见像 +* 的操作符, for 循环也是一个例子)。 只要能在右侧调用所需数量的组件函数,任何东西都可以放在解构声明的右侧。 当然,还可以有 component3()component4() 等等。

解构声明同样适用于 for 循环:

for ((a, b) in collection) { ... }

变量 ab 获取集合元素调用 component1()component2() 返回的值。

示例:从函数返回两个值

假设你需要从函数返回两样东西 —— 例如,一个结果对象和某种状态。 在 Kotlin 中,有一种简洁的方法,我们可以声明一个 数据类 并返回它的实例:

data class Result(val result: Int, val status: Status) fun function(...): Result { // 计算 return Result(result, status) } // 现在,使用这个函数: val (result, status) = function(...)

由于数据类自动声明了 componentN() 函数,所以解构声明在这里有效的。

示例:解构声明和 Map 映射

遍历映射可能最好的方式是这样:

for ((key, value) in map) { // 对键和值进行处理 }

要实现这一点,你应该

  • 通过提供 iterator() 函数将映射表示为一系列值。

  • 通过提供 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()

因此,你可以在 for 循环中自由地使用解构声明处理映射(以及数据类实例的集合或类似的情况)。

用下划线表示未使用的变量

如果在解构声明中不需要某个变量,可以用下划线代替其名称:

val (_, status) = getResult()

对于以这种方式跳过的组件,不会调用 componentN() 操作符函数。

在 lambda 中进行解构

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

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

注意声明两个参数和声明一个解构组作为参数的区别:

{ a -> ... } // 一个参数 { a, b -> ... } // 两个参数 { (a, b) -> ... } // 一个解构对 { (a, b), c -> ... } // 一个解构组和另一个参数

如果解构参数的某个组件未使用,你可以用下划线代替它的名称以避免命名:

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

你可以为整个解构参数或特定组件分别指定类型:

map.mapValues { (_, value): Map.Entry<Int, String> -> "$value!" } map.mapValues { (_, value: String) -> "$value!" }
Last modified: 08 九月 2024