📜  Kotlin数据类

📅  最后修改于: 2020-10-05 14:43:46             🧑  作者: Mango

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

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

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

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

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

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


Kotlin数据类别要求

要求如下:

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

示例:Kotlin数据类
data class User(val name: String, val age: Int)

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

运行该程序时,输出为:

name = jack
age = 29

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

让我们使用以下功能:


复制中

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

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

fun main(args: Array) {
    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}")
}

运行该程序时,输出为:

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

toString()方法

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

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

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

运行该程序时,输出为:

User(name=John, age=29)

hashCode()和equals()

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

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

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

fun main(args: Array) {
    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.")
}

运行该程序时,输出为:

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

销毁声明

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

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

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

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

运行该程序时,输出为:

name = John
age = 29
gender = Male

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

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

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

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

运行该程序时,输出为:

John
29
Male