数据类
Kotlin 中的数据类主要用于保存数据。 对于每个数据类,编译器会自动生成额外的成员函数,这些函数允许你将实例打印为可读输出、比较实例、复制实例等。 数据类使用 data
标记:
编译器会自动根据主构造函数中声明的属性生成以下成员:
equals()
/hashCode()
配对。toString()
形式为"User(name=John, age=42)"
。与声明顺序对应的
componentN()
函数。copy()
函数(见下文)。
为了确保生成的代码一致并且具有有意义的行为,数据类必须符合以下规定:
主构造函数必须至少有一个参数。
所有主构造函数的参数必须标记为
val
或var
。数据类不能是抽象的、开放的、封闭的 或 内部的。
此外,关于数据类成员的生成,遵循以下继承规则:
如果在数据类的主体中有
equals()
、hashCode()
或toString()
的显式实现,或者在超类中有final
实现,则这些函数不会被生成,现有的实现将被使用。如果超类型具有
open
的componentN()
函数并且返回兼容类型,则为数据类生成相应的函数,并重写超类型中的函数。 如果由于签名不兼容或函数为final
,无法重写超类型的函数,则会报告错误。不允许为
componentN()
和copy()
函数提供显式实现。
数据类可以扩展其他类(参见密封类以获取示例)。
在类体中声明的属性
编译器只利用主构造函数内定义的属性来自动生成函数。若要排除某个属性不纳入生成的实现中,请将其声明在类体内:
在下面的示例中,只有 name
属性在 toString()
、 equals()
、 hashCode()
和 copy()
实现中被默认使用,并且只有一个组件函数 component1()
。 age
属性是在类体内部声明的,因此被排除在外。 因此,两个 Person
对象如果 name
相同但 age
值不同,它们会被认为是相等的,因为 equals()
只评估来自主构造函数的属性:
复制
使用 copy()
函数复制一个对象,允许你在保持其余属性不变的情况下修改部分属性。 上面 User
类的此函数实现如下:
之后,你可以这样写:
数据类和解构声明
为数据类生成的 组件函数 使它们可以在 解构声明 中使用:
标准数据类
标准库提供了 Pair
和 Triple
类。 然而,在大多数情况下,命名的数据类是更好的设计选择,因为它们通过为属性提供有意义的名称,使代码更易读。