# Kotlin 数据类

> 原文： [https://www.programiz.com/kotlin-programming/data-class](https://www.programiz.com/kotlin-programming/data-class)

#### 在本文中，您将学习在 Kotlin 中创建数据类。 您还将了解数据类必须满足的要求及其标准功能。

可能会出现一种情况，您需要创建一个仅用于保存数据的类。 在这种情况下，您可以将类别标记为`data`以创建数据类别。 例如，

```kt
data class Person(val name: String, var age: Int)
```

对于此类，编译器会自动生成：

*   主要构造器的`copy()`函数，`equals()`和`hashCode()`对以及`toString()`形式
*   `componentN()`函数

在详细讨论这些功能之前，让我们讨论数据类必须满足的要求。

* * *

## Kotlin 数据类要求

要求如下：

*   主构造器必须至少具有一个参数。
*   主构造器的参数必须标记为`val`（只读）或`var`（读写）。
*   该类不能是开放的，抽象的，内部的或密封的。
*   该类可以扩展其他类或实现接口。 如果您使用的是 1.1 之前的 Kotlin 版本，则该类只能实现接口。

* * *

## 示例：Kotlin 数据类

```kt
data class User(val name: String, val age: Int)

fun main(args: Array<String>) {
    val jack = User("jack", 29)
    println("name = ${jack.name}")
    println("age = ${jack.age}")
}
```

运行该程序时，输出为：

```kt
name = jack
age = 29
```

* * *

声明数据类时，编译器会在后台自动生成一些函数，例如`toString()`，`equals()`和`hashcode()`等。 这有助于使代码简洁。 如果您使用过 Java，则需要编写很多样板代码。

让我们使用以下功能：

* * *

### `copy`

对于数据类，可以使用`copy()`函数创建一个对象的副本，该对象的某些属性有所不同。 运作方式如下：

```kt
data class User(val name: String, val age: Int)

fun main(args: Array<String>) {
    val u1 = User("John", 29)

    // using copy function to create an object
    val u2 = u1.copy(name = "Randy")

    println("u1: name = ${u1.name}, name = ${u1.age}")
    println("u2: name = ${u2.name}, name = ${u2.age}")
}
```

运行该程序时，输出为：

```kt
u1: name = John, name = 29
u2: name = Randy, name = 29
```

* * *

### `toString()`方法

[`toString()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/to-string.html "Kotlin toString()")函数返回对象的字符串表示形式。

```kt
data class User(val name: String, val age: Int)

fun main(args: Array<String>) {
    val u1 = User("John", 29)
    println(u1.toString())
}
```

运行该程序时，输出为：

```kt
User(name=John, age=29)
```

* * *

### `hashCode()`和`equals()`

`hasCode()`方法返回对象的哈希码。 如果两个对象相等，则`hashCode()`产生相同的整数结果。 **推荐阅读**： [`hashCode()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/hash-code.html "Kotlin hashCode()")

如果两个对象相等（具有相同的`hashCode()`），则`equals()`返回`true`。 如果对象不相等，则`equals()`返回`false`。 **推荐阅读**： [`equals()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/equals.html "Kotlin equals()")

```kt
data class User(val name: String, val age: Int)

fun main(args: Array<String>) {
    val u1 = User("John", 29)
    val u2 = u1.copy()
    val u3 = u1.copy(name = "Amanda")

    println("u1 hashcode = ${u1.hashCode()}")
    println("u2 hashcode = ${u2.hashCode()}")
    println("u3 hashcode = ${u3.hashCode()}")

    if (u1.equals(u2) == true)
        println("u1 is equal to u2.")
    else
        println("u1 is not equal to u2.")

    if (u1.equals(u3) == true)
        println("u1 is equal to u3.")
    else
        println("u1 is not equal to u3.")
}
```

运行该程序时，输出为：

```kt
u1 hashcode = 71750738
u2 hashcode = 71750738
u3 hashcode = 771732263
u1 is equal to u2.
u1 is not equal to u3.
```

* * *

### 解构声明

您可以使用[解构声明](https://kotlinlang.org/docs/reference/multi-declarations.html "Kotlin Destructing Declaration")将对象分解为多个变量。 例如：

```kt
data class User(val name: String, val age: Int, val gender: String)

fun main(args: Array<String>) {
    val u1 = User("John", 29, "Male")

    val (name, age, gender) = u1
    println("name = $name")
    println("age = $age")
    println("gender = $gender")
}
```

运行该程序时，输出为：

```kt
name = John
age = 29
gender = Male
```

这是可能的，因为编译器会为数据类生成`componentN()`函数的所有属性。 例如：

```kt
data class User(val name: String, val age: Int, val gender: String)

fun main(args: Array<String>) {
    val u1 = User("John", 29, "Male")

    println(u1.component1())     // John
    println(u1.component2())     // 29  
    println(u1.component3())     // "Male"
}
```

运行该程序时，输出为：

```kt
John
29
Male
```