_uiState.update { it.copy(isLoading = true) } 中copy函数解释一下

5 阅读2分钟

一、先记住一句话

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) }

逐行翻译:

  1. update:拿到当前状态 it
  2. it.copy(...)复制一个新对象
  3. isLoading = true:只把加载中改成 true
  4. 其他字段不动
  5. 把新对象设置给 StateFlow
  6. UI 收到新状态 → 自动刷新

七、最常用的 copy () 写法(你以后天天用)

kotlin

// 只改加载状态
it.copy(isLoading = true)

// 只改数据
it.copy(data = newData)

// 只改错误
it.copy(error = "网络失败")

// 同时改多个
it.copy(
    isLoading = false,
    data = newData,
    error = null
)

八、超级总结(3 句背会)

  1. copy() 是 data class 自带的复制函数
  2. 它会创建一个新对象
  3. 只修改你指定的字段,其他字段自动保留原值

StateFlow 为什么必须用?

因为 StateFlow 靠新对象触发更新。不改对象 → UI 不刷新!