# 數據類
我們經常要創建一個類,不做什么事只存儲數據。在這樣的類中一些標準的函數一般可機械地從數據中推導出來。在 Kotlin 中,有一種稱為 _data class_ 的,標記為 `data`:
``` kotlin
data class User(val name: String, val age: Int)
```
編譯器自動從主構造器中所聲明的全部屬性衍生出下列成員:
* 一組 `equals()`/`hashCode()`
* `“User(name=John, age=42)”` 形式的 `toString()`
* 與屬性聲明順序一致的 [`componentN()` 函數](multi-declarations.html)
* `copy()` 函數(下面說明)
如果在類體中明確地定義或是從基類繼承了這些函數其中的某些,它將不會被創建。
要確定生成的是有意義的代碼,數據類必須滿足下列必備條件:
* 主構造器需要至少一個形參;
* 所有的主構造器形參都要標記為 `val` 或 `var`;
* 數據類不能為 `abstract`、`open`、`sealed` 或 `inner`;
* (1.1 版之前)只能實現接口。
從版本 1.1 開始,數據類可以擴展其它類
在 JVM 上,如果生成的類需要有一個無參構造器,那么所有的屬性都得指定默認值(查看[構造器](classes.md#constructors))
``` kotlin
data class User(val name: String = "", val age: Int = 0)
```
## 復制
我們經常遇到需要復制一個對象,變更它的一些屬性,但保留其余未改變的情況。這就是 `copy()` 產生的目的。對于上面的 `User` 類,它的實現應該像下面這樣:
``` kotlin
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
```
這樣就允許我們這么寫
``` kotlin
val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)
```
## 數據類和析構聲明
_Component 函數_ 的生成是為了數據類能啟用它們的[析構聲明](multi-declarations.html):
``` kotlin
val jane = User("Jane", 35)
val (name, age) = jane
println("$name, $age years of age") // prints "Jane, 35 years of age"
```
## 標準數據類
標準庫提供了 `Pair` 和 `Triple`。大多數情況下,想一下,命名數據類是一個更好的選擇方案,因為它們通過為屬性提供有意義的名稱讓代碼更可讀。