为什么要用`val`类型声明`mutableLiveData`类?

huangapple go评论59阅读模式
英文:

Why declare mutableLiveData class with val type?

问题

为什么不使用 val 类型的 mutableLiveData 作为 var 类型的替代品呢?

能够在 val 类型上进行设置不是一种违规吗?


比如,例如:

  1. val 类型的示例
class LoadDetailViewModel : ViewModel() {

    private val _liveData = MutableLiveData<String>()
    val liveData: LiveData<String> get() = _liveData

    fun loadData() = viewModelScope.launch {
        _liveData.value = "value"
        _liveData.postValue("value")
    }
}

  1. 代码改为 var 类型
class LoadDetailViewModel : ViewModel() {

    private var _liveData = MutableLiveData<String>()
    var liveData: LiveData<String> get() = _liveData

    fun loadData() = viewModelScope.launch {
        _liveData.value = "value"
        _liveData.postValue("value")
    }
}

但结果仍然是等效的。
当我将 mutableLiveData 声明为 var 时不会出现错误,但我不知道为什么我必须将其声明为 val


  • 我理解 Kotlin 语言中的 val 类型是不可变类型,而 var 类型是可变类型。
  • 那么将其声明为 var 类型不是正确的吗?

Android 开发者文档
我查阅了 Android 官方文档,但没有找到答案。

英文:

Why not use mutableLiveData of the val type as a substitute for the var type?

Isn't it a violation to be able to set on the val type?


Like, for example:

  1. Example of a val type
class LoadDetailViewModel : ViewModel() {

    private val _liveData = MutableLiveData&lt;String&gt;()
    val liveData: LiveData&lt;String&gt; get() = _liveData

    fun loadData() = viewModelScope.launch {
        _liveData.value = &quot;value&quot;
        _liveData.postValue(&quot;value&quot;)
    }
}

  1. Code changed to var type
class LoadDetailViewModel : ViewModel() {

    private var _liveData = MutableLiveData&lt;String&gt;()
    var liveData: LiveData&lt;String&gt; get() = _liveData

    fun loadData() = viewModelScope.launch {
        _liveData.value = &quot;value&quot;
        _liveData.postValue(&quot;value&quot;)
    }
}

But the result is still equivalent.
There is no error when I declare mutableLiveData as var, but I don't know why I have to declare it as val.


  • I understand that the val type in the Kotlin language is an immutable type, and the var type is a mutable type.
  • Then isn't it right to declare it as a var type?

Android Developers
I looked up the official documents of Android, but there was no answer to them.

答案1

得分: 3

当你调用 _liveData.value = "value" 时,请注意你没有使用 _liveData =。因此,你并没有改变属性 _liveData,它不需要是一个 var。你是在改变 MutableLiveData 内部的属性。

对于这个情况来说,使用 var 是错误的,因为你没有替换 MutableLiveData 的实例。如果你将其更改为不同的实例,观察者将不会收到通知。

你混淆了属性的可变性(它持有 MutableLiveData 实例的引用)和类的可变性(MutableLiveData 本身)。MutableLiveData 是一个可变类,因为它内部有可变变量。你可以对它进行改变,但你不想改变持有对它的引用的属性。

使用 var 并不会引起任何问题,因为你实际上并没有利用可变性来更改引用到不同实例的情况。但是,由于你永远不应该这样做,所以没有理由使用 var 而不是 val。使用 val 会使代码更清晰,更健壮。

英文:

When you call _liveData.value = &quot;value&quot;, notice you are not using _liveData =. So you are not mutating the property _liveData and it doesn't need to be a var. You are mutating the property inside the MutableLiveData.

It is wrong to use var for this, because you are not swapping out the instance of MutableLiveData. If you changed it to a different instance, your observers would not be notified.

You are confusing mutability of the property (the thing that holds a reference to an instance of MutableLiveData) with the class (the MutableLiveData itself). MutableLiveData is a mutable class because it has mutable variables inside it. You can mutate it, but you don't want to mutate the property that is holding a reference to it.

Using var isn't causing any problems because you haven't actually utilized the mutability to change the reference to a different instance. But since you should never want to do that, there is no reason to use var instead of val. It makes code clearer and more robust to use val.

huangapple
  • 本文由 发表于 2023年3月31日 21:22:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899033.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定