# 解构声明
有时一个对象会很方便地解构到一系列变量中,例如:
``` kotlin
val (name, age) = person
```
这种语法称为_解构声明_。解构声明一次性创建多个变量。我们已经声明了两个新变量:`name` 和 `age`,并能够独立地使用它们:
``` kotlin
println(name)
println(age)
```
解构声明会编译成下面的代码:
``` kotlin
val name = person.component1()
val age = person.component2()
```
这里的 `component1()` and `component2()` 函数是在 Kotlin 广泛使用的_约定原则_(查看运算符,如 `+` 和 `*`,`for` 循环等等。)。解构声明的右手边可以是任何东西,只要有必需数量的 component 函数能在它上面调用。而且理所当然地是 `component3()` 和 `component4()`,以此类推。
注意 `componentN()` 函数需要与 `operator` 关键字一起标记以允许在解构声明中使用它们。
解构声明也在 `for` 循环中工作:当你说
``` kotlin
for ((a, b) in collection) { ... }
```
变量 `a` 和 `b` 获得在集合的元素上调用 `component1()` 和 `component2()` 而返回的值。
## 示例:从一个函数返回两个值
让我们说说我们需要从一个函数返回两个东西。例如,一定顺序下的一个结果对象和一个状态。Kotlin 中做这件事的一个简便的方式是声明一个[数据类](data-classes.html)并返回它的实例:
``` kotlin
data class Result(val result: Int, val status: Status)
fun function(...): Result {
// 计算
return Result(result, status)
}
// 现在,要使用这个函数:
val (result, status) = function(...)
```
数据类自动地声明 `componentN()` 函数,这里解构声明可以正常工作。
**注意**:我们也能使用标准类 `Pair` 并有 `function()` 返回 `Pair<Int, Status>`,但它往往有更好的数据命名属性。
## 示例:解构声明和映射
或许遍历一个映射最佳的方式是这样的:
``` kotlin
for ((key, value) in map) {
// 拿这对键和值做点什么
}
```
要让这正常工作,我们得
* 通过提供一个 `iterator()` 函数让映射表现得像一个队列值,
* 通过提供函数 `component1()` and `component2()` 让每组元素表现得像一对。
而且事实上,标准库提供了这些扩展:
``` kotlin
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` 循环(数据类实例的集合等等也一样)中自由地使用解构声明。