一、数据类 data class
我们经常会创建一些保存数据的类,Kotlin 使用 data 关键字声明一个数据类,解决 JavaBean 极其臃肿的写法。主构造中声明的属性会默认创建以下函数(在类体中声明的属性不会生成):
- equals()、hashCode()
- toString(),格式是:User(name=张三, age=18)
- componentN(),按声明顺序对应所有属性
- copy()
data class User(
var id: Long,
var name: String,
var age: Int
) : Person() {
var gender : Boolean = false //类中声明的属性不会自动生成
}
//创建实例
val user = User(123456, "张三", 18)
//通常取出数据
val id = user.id
//使用解构一次声明多个变量
var (_, name, age) = user //必须按顺序声明,可以使用下划线忽略不需要的属性
//使用变量
name = "李四"
println(name) //打印:李四
println(age) //打印:18
//再想创建一个User只改变年龄
val user2 = user.copy(age = 31)
println(user) //打印:User(id=123456, name='张三', age=18)
println(user2) //打印:User(id=123456, name='张三', age=31)
二、解构 componentN( )
就是把一个对象的属性一次性拆分成多个变量。数据类默认生成 componentN() 函数,N对应主构造中属性的个数。普通类也可以使用解构,需要自行手动声明 operator componentN() 函数。
class User(
var id: Long,
var name: String,
var age: Int
) {
operator fun component1() = id
operator fun component2() = name
operator fun component3() = age
}
fun main() {
val user = User(123456, "张三", 18)
//普通方式赋值
val id = user.id
//必须按顺序声明,可以使用下划线忽略不需要的属性,变量名不必和属性名相同
var (_, n, age) = user
n = "李四"
println(n) //打印:李四
println(age) //打印:18
}
2.1 基于名称的结构
v2.3 引入。之前解构需要依赖于 componentN() 的位置顺序,这在修改数据类字段顺序时容易引发隐蔽 Bug。
val user = User(123456, "张三", 18)
val (name = n, age = a) = user
三、拷贝 copy( )
很多情况下,我们需要复制一个对象,只改变部分数据而其它保持不变,就可以使用 copy() 函数。
class User(
var id: Long,
var name: String,
var age: Int
) {
fun copy(
id: Long = this.id,
name: String = this.name,
age: Int = this.age
) = User(
id = id,
name = name,
age = age
)
}
val aa = User(123,"张三",18)
val bb = aa.copy(name = "李四")
println("${aa.id},${aa.name},${aa.age}") //打印:123,张三,18
println("${bb.id},${bb.name},${bb.age}") //打印:123,李四,18
v2.3 引入。数据类的 copy() 方法一直有个痛点:无法在接口中使用,且深层拷贝麻烦。2.3 引入了新的 DSL 风格的拷贝机制(部分实验性)。
val bb = aa.copy {
name = "李四" //看起来像构建器,但实际上是不可变拷贝
}
本文介绍了Kotlin中的数据类,展示了如何使用data关键字简化JavaBean的编写,包括默认生成的equals(), hashCode(), toString()等方法。还讨论了解构、copy()函数的用法,以及如何自定义组件函数来实现对象属性的拆分和复制。通过实例演示了如何通过copy()方法创建对象副本并修改特定属性,以保持不变的数据。
1832

被折叠的 条评论
为什么被折叠?



