kotlin - 为什么作者可以通过 update 将新对象重新分配给 val?
问题描述
解决方案
The val
keyword only refers to which object the variable holds, not the data inside said object. For example:
class MyClass(var value: Int)
The following code is not allowed:
val obj = MyClass(5)
obj = MyClass(7) // compile error
because the val
keyword refers to the variable itself being reassigned to a different object. This code, however, is allowed:
val obj = MyClass(5)
obj.value = 7
Here, obj is still the same object, only a property of said object changed value. In your provided code, the update function modifies data stored inside the _uiState
object, however it does not swap it for a new object. This is important because:
var obj = MyClass(5)
val copy = obj
obj = MyClass(7)
println(copy.value) // prints 5
println(obj.value) // prints 7
When reassigning a variable, the old object remains, and any other variables referencing that object are not updated. In your case, _uiState.value
is modified, not the variable itself. Hope this clears things up!
Edit:
Yes, it.copy()
is an expression which creates a new object. However, this code is executed in the line _uiState.update { it.copy(loading = true) }
, in the refreshAll()
function. As it is the last statement in a lambda expression (also the only one, but doesn't matter), it is the return value of said lambda. Here we have to look at the declaration of the update function.
The lambda is stored in the function
variable (of type (T)->T
). This means, whenever function()
is called, the code inside the lambda is executed, and its result (a new object) is then returned by the function()
call. This value is assigned to the val nextValue
variable and not to _uiState
itself. The compareAndSet
function modifies _uiState.value
and does not change the object the _uiState
variable references.
And by the way, the object returned by it.copy()
is of type T, and not of type MutableStateFlow<T>
, which your _uiState
variable holds. T is the type of _uiState.value
.
推荐阅读
- sql-server - 在高峰时间更改存储过程会导致表锁定吗?
- node.js - 从 rsa 密钥获取 »fingerprint«
- django - 使用 Django 的 I18n 函数和代码中的键而不是默认的英文
- python - 对正则表达式中已经分组的内容进行分组
- javascript - setState ReactJS 的问题,在 todoList 中完成
- android - 使用匕首 2 在 Kotlin 中的 AppWidgetProvider 中的字段注入
- html - Bootstrap 4 右对齐文本
- python - 无法删除文件夹
- highcharts - 使用 Karma + Jasmine 的单元测试未涵盖 Highcharts 功能
- spring-integration - TcpMessageMapper - 使用 FailoverClientConnectionFactory 时来自连接 xxxx:xxxx:0e07144c-456e-4e31-a93c-66926b8f7018 的空负载