使用 copy() 复制与部分覆盖
使用 copy() 创建修改后的实例,而不改变原始实例。
第 2 / 4 课13 个步骤
使用 copy() 复制与部分覆盖 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。
使用 copy() 进行不可变更新
copy() 会创建一个数据类的新实例,并修改其中的某些属性。未指定的属性会保留原始值。
基本 copy()
传入命名参数即可覆盖指定属性。
data class Person(val name: String, val age: Int, val city: String)
val alice = Person("Alice", 30, "Berlin")
val olderAlice = alice.copy(age = 31)
println(olderAlice) // Person(name=Alice, age=31, city=Berlin)复制多个字段
根据需要覆盖任意数量的字段。
data class Config(val host: String, val port: Int, val ssl: Boolean, val timeout: Int)
val prod = Config("prod.server", 443, true, 30)
val test = prod.copy(host = "test.server", port = 8080, ssl = false)
println(test)copy 不会修改原对象
copy 始终会创建一个新对象,原对象完全不会改变。
data class Point(val x: Int, val y: Int)
val origin = Point(0, 0)
val moved = origin.copy(x = 5)
println(origin) // Point(x=0, y=0) — unchanged
println(moved) // Point(x=5, y=0)深拷贝注意事项
copy 是浅拷贝。数据类中的可变对象会由原对象和副本共享。
data class Team(val name: String, val members: MutableList<String>)
val t1 = Team("A", mutableListOf("Alice"))
val t2 = t1.copy(name = "B")
t2.members.add("Bob") // modifies SHARED list!
println(t1.members) // [Alice, Bob] ← also changed!避免浅拷贝问题
在数据类中使用不可变数据,以避免共享问题。
data class Team(val name: String, val members: List<String>) // immutable list
val t1 = Team("A", listOf("Alice"))
val t2 = t1.copy(name = "B", members = t1.members + "Bob")
println(t1.members) // [Alice]
println(t2.members) // [Alice, Bob]copy 在状态管理中的应用
在 Redux 风格或 MVI 架构中,copy 是更新状态的惯用方式。
data class UiState(val loading: Boolean, val items: List<String>, val error: String?)
fun reduce(state: UiState, action: Action) = when (action) {
is Loading -> state.copy(loading = true)
is Success -> state.copy(loading = false, items = action.data)
is Error -> state.copy(loading = false, error = action.msg)
}带默认参数的 copy
即使数据类包含许多属性,命名参数也能让 copy 依然易于使用。
data class Article(
val id: Long, val title: String, val body: String,
val published: Boolean = false, val views: Int = 0
)
val draft = Article(1L, "Hello", "Content...")
val published = draft.copy(published = true)
println(published.title) // Hello在测试中使用 copy
copy 让测试夹具更容易创建——先创建一个基础对象,再只修改所需的字段。
val baseUser = User(id = 1, name = "Test", email = "test@test.com", active = true)
val inactiveUser = baseUser.copy(active = false)
val renamed = baseUser.copy(name = "Renamed")copy 与构建器模式
数据类的 copy() 是 Kotlin 对构建器模式的回应。对于包含许多可选字段的复杂对象,使用数据类加 copy 更简洁。
// Java Builder:
User.builder().name("A").age(30).role("admin").build()
// Kotlin:
val u = User("A", 30, "admin") // or copy from base记录语义
具有 val 属性的数据类表现得类似 Java 记录(JDK 16 及更高版本)——不可变、基于值,并且会自动转换为可打印形式。
data class RGB(val r: Int, val g: Int, val b: Int)
val white = RGB(255, 255, 255)
println(white) // RGB(r=255, g=255, b=255)快速检查
对数据类实例调用 copy() 后,原实例会发生什么?
回顾
copy() 会创建一个覆盖了指定字段的新实例,原实例保持不变。它非常适合状态管理、测试和构建器风格的构造。请注意可变属性带来的浅拷贝问题。下一步:解构!
免费开始
用 AI 导师学习 Kotlin — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 51
- 课程
- 203
常见问题解答
「使用 copy() 复制与部分覆盖」课时是免费的吗?
是的 — 「使用 copy() 复制与部分覆盖」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。
「使用 copy() 复制与部分覆盖」这节课中我会学到什么?
使用 copy() 创建修改后的实例,而不改变原始实例。 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Kotlin Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「使用 copy() 复制与部分覆盖」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Kotlin Academy 课中编写并运行代码吗?
能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 数据类基础:自动生成的方法
- 使用 copy() 复制与部分覆盖
- 使用 componentN 进行解构声明
- 集合中的数据类与作为 Map 键