如何在修改后获取新的不可变对象?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
相关产品推荐
相关产品推荐

