一、先记住一句话
copy() = 复制一个新对象,只改你想改的字段,其他不变
而且它是 Kotlin 数据类(data class)自带的函数,不用你写。
二、先看你的 UiState 长什么样
你一定是这样定义的:
kotlin
data class UiState(
val isLoading: Boolean = false,
val data: String? = null,
val error: String? = null
)
因为是 data class,所以自动拥有:
equals()hashCode()copy()toString()
三、copy() 到底做了什么?
我用大白话翻译:
kotlin
it.copy(isLoading = true)
等于:
1. 拿当前旧对象
2. 复制一份 全新对象
3. 只把 isLoading 改成 true
4. 其他字段(data、error)完全保持不变
5. 返回这个新对象
四、用代码模拟 copy () 内部做的事(你马上懂)
kotlin
fun copy(
isLoading: Boolean = this.isLoading, // 不传就用旧值
data: String? = this.data, // 不传就用旧值
error: String? = this.error // 不传就用旧值
): UiState {
return UiState(isLoading, data, error) // 返回新对象!
}
所以:
kotlin
old.copy(isLoading = true)
就等于:
kotlin
UiState(
isLoading = true, // 你改的
data = old.data, // 自动保留
error = old.error // 自动保留
)
五、为什么 StateFlow 必须用 copy ()?
重点来了!
StateFlow 只有在 “对象变了” 才会通知刷新
StateFlow 比较的是:
新值 === 旧值?(引用是否相同)
如果你这样写:
kotlin
val newState = old
newState.isLoading = true // 错误!val 还不能改
这叫 改原对象内容,对象没变 → StateFlow 不更新 UI。
正确做法:产生新对象 → StateFlow 才会更新
kotlin
val newState = old.copy(isLoading = true)
✅ 新对象
✅ StateFlow 检测到变化
✅ UI 自动刷新
六、回到你这句代码,彻底看懂
kotlin
_uiState.update { it.copy(isLoading = true) }
逐行翻译:
update:拿到当前状态itit.copy(...):复制一个新对象isLoading = true:只把加载中改成 true- 其他字段不动
- 把新对象设置给 StateFlow
- UI 收到新状态 → 自动刷新
七、最常用的 copy () 写法(你以后天天用)
kotlin
// 只改加载状态
it.copy(isLoading = true)
// 只改数据
it.copy(data = newData)
// 只改错误
it.copy(error = "网络失败")
// 同时改多个
it.copy(
isLoading = false,
data = newData,
error = null
)
八、超级总结(3 句背会)
copy()是 data class 自带的复制函数- 它会创建一个新对象
- 只修改你指定的字段,其他字段自动保留原值
StateFlow 为什么必须用?
因为 StateFlow 靠新对象触发更新。不改对象 → UI 不刷新!