Why can the immutable variables change sometimes?
-
At the bottom of the example where the value of the LiveData object changes, although it is said everywhere that immutable cannot be changed. Explain that I don't understand.
class RestaurantViewModel @Inject constructor( api: RestaurantApi ) : ViewModel() { private val restaurantsLiveData = MutableLiveData<List<Restaurant>>() val restaurants: LiveData<List<Restaurant>> = restaurantsLiveData //та часть которую я не понимаю. //то есть мы можем менять значение MutableLiveData и присваивая это значение по сути делаем LiveData меняемым? init { viewModelScope.launch { val restaurants = api.getRestaurants() delay(2000) restaurantsLiveData.value = restaurants } } }
And why couldn't you come up with something that wouldn't make MutableLiveData and then send it to LiveData?
-
val
indicates the variable that the reference to the object is unchanged. But with one of the properties of the PLO... https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D0%BA%D0%B0%D0%BF%D1%81%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) (the object may change its contents from inside), the meaning is not the same.MutableLiveData
- as I've said, I'm changing. But not MutableLiveData itself is changing, but her contents are in the class that it returns.A simpler version of the collection:
// делаем в классе мутабельную переменную class Foo(var value: String)
object Bar {
// создаём переменную, где не меняется ссылка
val foo: Foo = Foo("something")
}fun main() {
// сохраним что-бы потом проверить одинаковые ли объекты
val preEditedValue = Bar.foo// значение меняется
Bar.foo.value = "Test"
// проверяем на Referential equality
println(preEditedValue === Bar.foo)
}
The point is, to conceal the mutation of data for public access (e.g., in your example, View, nothing should change directly
MutableLiveData
) there andLiveData
which prevents the possibility of altering data where it should not be. It's not something new, like in the Kotlin, that's what you think, starting with the collection--MutableCollection
♪Collection
, ending with LiveData -MutableStateFlow
♪StateFlow
♪Mobility should never be made public access to avoid problems. Control of data flows is easier in one class.
Possible solution (as I do)
For ViewModel, I'm creating an abstract class that defines everything that's gonna come out:
abstract class MyViewModel : ViewModel() {
abstract val list: LiveData<List<String>>abstract fun addItem(item: String)
}
Then I create a "integrated" version of ViewModel'i.
fun MyViewModel(): MyViewModel = IntegratedMyViewModel()
private class IntegratedMyViewModel : MyViewModel() {
override val list: MutableLiveData<List<String>> = MutableLiveData(listOf())
override fun addItem(item: String) {
list.value = list.value.toMutableList().apply { add(item) }
}
}
Sugar is that, in fact, mutatity is not coming out (at least you can't legally access the mutate liquette).