You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在修改后获取新的不可变对象?Kotlin技术方案咨询

嵌套不可变对象的便捷修改方案

假设你有一个庞大的嵌套对象,想要修改其中某个属性,直观写法大概是这样:

myData.x.y.z = 7;
// or...
myData.a.b.add(9);

但实际编码里根本没这么简单。

比如在Android的ViewModel中,基于单一数据源和单向数据流原则,必须使用不可变数据(Kotlin里通过val关键字实现),代码会变成这样:

data class Employee(
  val name: String
)

data class Company(
  val employees: List<Employee>
)

class MyViewModel : ViewModel() {

  // 暴露界面UI状态
  private val _uiState = MutableStateFlow(Company(emptyList()))
  val uiState: StateFlow<Company> = _uiState.asStateFlow()

  // 处理业务逻辑
  fun addEmployee(employee: Employee) {
    _uiState.update { currentState ->
      currentState.copy(
        employees = buildList {
          addAll(currentState.employees)
          add(employee)
        }
      )
    }
  }
}

上面的对象嵌套层级不深,只是实现添加功能。如果要更新List里的元素,代码会更繁琐;要是遇到深度嵌套的对象,层层copy不仅写起来麻烦,还可能带来性能问题。

比如更新员工信息的代码:

fun updateEmployee(employee: Employee) {
  _uiState.update { currentState ->
    currentState.copy(
      employees = buildList {
        val index = currentState.employees.indexOfFirst { it.name == employee.name }
        val temp = currentState.employees.toMutableList()
        temp[index] = Employee("jack")
        temp.toList()
      }
    )
  }
}

深度嵌套对象的更新更是繁琐:

data class A(
  val b: B
)

data class B(
  val c: C
)

data class C(
  val d: D
)

data class D(
  val name: String
)

class MyViewModel : ViewModel() {
  fun updateDName() {
    _uiState.update { currentState ->
      currentState.copy(
        b = currentState.b.copy(
          c = currentState.b.c.copy(
            d = currentState.b.c.d.copy(
              name = "John"
            )
          )
        )
      )
    }
  }
}

有没有类似下面代码里doSomeThing这样的方法?能自动创建对象副本,允许我们在副本上修改属性,最后返回这个新的不可变对象:

fun addEmployee(employee: Employee) {
  _uiState.update { currentState ->
    doSomeThing {
      currentState.employees.add(employee)
    }
  }
}

内容的提问来源于stack exchange,提问作者SageJustus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:35:11