LiveData "pass-by-reference" 初始值

LiveData "pass-by-reference" initial value

我有一个 ViewModel class 看起来像这样:

class EditUserViewModel(
    private val initUser: User,
) : ViewModel() {

    private val _user = MutableLiveData(initUser)
    val user: LiveData<User>
        get() = _user

    fun hasUserChanged() = initUser != _user.value

}

User可以通过UI.
更新用户数据class实例的一些属性 要检查从片段导航时是否有任何更改,我使用 hasUserChanged 方法。
问题是它总是错误的。我检查了一下,似乎每次更改 _user MutableLiveData.
initialUser 都会更改 这是为什么? MutableLiveData 的初始值是通过引用传递的吗?我一直认为Kotlin是一种“传值”类型的语言。

更新: 在将 initUser 放入 MutableLiveData.

之前复制 initUser 时,问题似乎消失了
private val _user = MutableLiveData(initUser.copy())

但我仍然不明白为什么我必须这样做。

Kotlin 就像 java 而它们是 pass-by-value。如果您在 User class 中实现 equals 函数,或者将其设置为 data class (隐式实现 equals 函数),则可以确保用户对象的内容由 != 运算符检查。

更新

如果您直接更改 LiveData 的值,例如这样:

_user.value.name = "some name"

这意味着你正在改变initUsername 属性,因为_user.value恰好是指initUser所做的对象。因此,!= 运算符总是 returns 假,因为我们有一个对象有两个对它的引用。

现在,当您这样做时:

private val _user = MutableLiveData(initUser.copy())

您正在创建 initUser 的深层副本(我们称之为 X),它是内存中的新对象,具有与 initUser 相同的 属性 值。

因此,通过更改其属性,例如:_user.value.name = "some name",实际上,您是在 X 而不是 initUser 上进行此更改。它导致保留 initUser 中的初始值,意思是不要更改它们,并解决问题。