**已关闭。**此问题正在寻求有关书籍、工具、软件库等的建议。它不符合Stack Overflow guidelines准则。当前不接受答案。
我们不允许问题寻求有关书籍、工具、软件库等的推荐。你可以编辑问题,以便可以使用事实和引用来回答问题。
昨天关门了。
这篇文章是昨天编辑并提交审查的。
Improve this question
假设您有一个巨大的嵌套对象,然后您想修改它的一个属性。
myData.x.y.z = 7;
// or...
myData.a.b.add(9);
这看起来不是什么大问题,但实际的编码并不那么简单。
data class Employee(
val name: String
)
data class Company(
val employees: List<Employee>
)
class MyViewModel : ViewModel() {
// Expose screen UI state
private val _uiState = MutableStateFlow(Company(emptyList()))
val uiState: StateFlow<Company> = _uiState.asStateFlow()
// Handle business logic
fun addEmployee(employee: Employee) {
_uiState.update { currentState ->
currentState.copy(
employees = buildList {
addAll(currentState.employees)
add(employee)
}
)
}
}
}
在真实的代码中,基于单一真实数据源和单向数据流原则,必须使用不可变数据,这在Kotlin中通过val
关键字实现。
这个对象的嵌套层次不是特别深,实现的函数是add
,如果要更新List
中的元素,代码会比较复杂,copy
一个嵌套很深的对象也会造成性能问题。
因此,我希望有一个如下所示的方法doSomeThing
,它创建对象的副本,根据需要修改新对象的属性,并返回这个新对象。
fun addEmployee(employee: Employee) {
_uiState.update { currentState ->
doSomeThing {
currentState.employees.add(employee)
}
}
}
下面添加了一些示例。
第一次编辑2023-3-14 19:47:42
将“addEmployee()”函数更改为“updateEmployee()”函数。
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 updateEmployee(employee: Employee) {
_uiState.update { currentState ->
currentState.copy(
b = currentState.b.copy(
c = currentState.b.c.copy(
d = currentState.b.c.d.copy(
name = "John"
)
)
)
)
}
}
}
1条答案
按热度按时间wydwbb8l1#
Kotlin已经可以做到这一点,而无需显式突变:
还有Kotlin
List
和MutableList
、Set
和MutableSet
以及其他集合之间的分隔map
、flatMap
、reduce
、fold
、drop
、take
等复制深度嵌套的对象也会导致性能问题
不多。当你修补一个字段时,副本的其他字段的值仍然指向相同的对象。