Why are MutableLiveData variables declared with equals sign (=)?

Viewed 377

In Kotlin, when declaring the type of variable, a colon is used. Even when declaring LiveData, a colon is used. So why is an equals sign used for MutableLiveData? I haven't been able to figure this out. I spent about 2 hours a few days ago trying to understand why my MutableLiveData variable wasn't working only to realize I needed an equals instead of a colon.

Example:

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

Thanks in advance!

3 Answers
val liveData: LiveData<Int>

is not meaningful by itself. It also needs to be initialized. I suspect you are looking at a rather common idiom in Android programming, but missed that the next line is still part of definition of liveData:

val liveData: LiveData<Int>
  get() = _liveData

Here the reason you need : LiveData<Int> is only because otherwise Kotlin would infer the same type MutableLiveData<Int> for liveData as for _liveData, and the entire point of this idiom is to stop other classes from calling postValue/setValue on it.

Kotlin auto detects the type, so you do not need to specify it. These are equivalent

val foo: Int = 123
val foo = 123

However, if you have a variable that is initialized later, you must provide the type, as otherwise the compiler can't determine what type it is. For instance,

class MyClass {
    val foo: Int  // must specify type

    init {
        foo = /* compute foo */
    }
}

It has nothing to do with LiveData or MutableLiveData.

So why is an equals sign used for MutableLiveData?

Because you are creating an instance of MutableLiveData, via its constructor. You are not providing a type — the Kotlin compiler is inferring it from the type of the object you are assigning to the property.

Basically, your statement is shorthand for:

private val _liveData: MutableLiveData<Int> = MutableLiveData<Int>()

You can learn more about type inference in Google's Kotlin docs.

Related