原文: https://www.programiz.com/kotlin-programming/data-class

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

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

  1. data class Person(val name: String, var age: Int)

对于此类,编译器会自动生成:

  • 主要构造器的copy()函数,equals()hashCode()对以及toString()形式
  • componentN()函数

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


Kotlin 数据类要求

要求如下:

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

示例:Kotlin 数据类

  1. data class User(val name: String, val age: Int)
  2. fun main(args: Array<String>) {
  3. val jack = User("jack", 29)
  4. println("name = ${jack.name}")
  5. println("age = ${jack.age}")
  6. }

运行该程序时,输出为:

  1. name = jack
  2. age = 29

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

让我们使用以下函数:


copy

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

  1. data class User(val name: String, val age: Int)
  2. fun main(args: Array<String>) {
  3. val u1 = User("John", 29)
  4. // using copy function to create an object
  5. val u2 = u1.copy(name = "Randy")
  6. println("u1: name = ${u1.name}, name = ${u1.age}")
  7. println("u2: name = ${u2.name}, name = ${u2.age}")
  8. }

运行该程序时,输出为:

  1. u1: name = John, name = 29
  2. u2: name = Randy, name = 29

toString()方法

toString()函数返回对象的字符串表示形式。

  1. data class User(val name: String, val age: Int)
  2. fun main(args: Array<String>) {
  3. val u1 = User("John", 29)
  4. println(u1.toString())
  5. }

运行该程序时,输出为:

  1. User(name=John, age=29)

hashCode()equals()

hasCode()方法返回对象的哈希码。 如果两个对象相等,则hashCode()产生相同的整数结果。 推荐阅读hashCode()

如果两个对象相等(具有相同的hashCode()),则equals()返回true。 如果对象不相等,则equals()返回false推荐阅读equals()

  1. data class User(val name: String, val age: Int)
  2. fun main(args: Array<String>) {
  3. val u1 = User("John", 29)
  4. val u2 = u1.copy()
  5. val u3 = u1.copy(name = "Amanda")
  6. println("u1 hashcode = ${u1.hashCode()}")
  7. println("u2 hashcode = ${u2.hashCode()}")
  8. println("u3 hashcode = ${u3.hashCode()}")
  9. if (u1.equals(u2) == true)
  10. println("u1 is equal to u2.")
  11. else
  12. println("u1 is not equal to u2.")
  13. if (u1.equals(u3) == true)
  14. println("u1 is equal to u3.")
  15. else
  16. println("u1 is not equal to u3.")
  17. }

运行该程序时,输出为:

  1. u1 hashcode = 71750738
  2. u2 hashcode = 71750738
  3. u3 hashcode = 771732263
  4. u1 is equal to u2.
  5. u1 is not equal to u3.

解构声明

您可以使用解构声明将对象分解为多个变量。 例如:

  1. data class User(val name: String, val age: Int, val gender: String)
  2. fun main(args: Array<String>) {
  3. val u1 = User("John", 29, "Male")
  4. val (name, age, gender) = u1
  5. println("name = $name")
  6. println("age = $age")
  7. println("gender = $gender")
  8. }

运行该程序时,输出为:

  1. name = John
  2. age = 29
  3. gender = Male

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

  1. data class User(val name: String, val age: Int, val gender: String)
  2. fun main(args: Array<String>) {
  3. val u1 = User("John", 29, "Male")
  4. println(u1.component1()) // John
  5. println(u1.component2()) // 29
  6. println(u1.component3()) // "Male"
  7. }

运行该程序时,输出为:

  1. John
  2. 29
  3. Male