🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 数据类 我们经常要创建一个类,不做什么事只存储数据。在这样的类中一些标准的函数一般可机械地从数据中推导出来。在 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`。大多数情况下,想一下,命名数据类是一个更好的选择方案,因为它们通过为属性提供有意义的名称让代码更可读。