Home > Software design >  Kotlin cannot make out that I've already checked whether the item is in the collection
Kotlin cannot make out that I've already checked whether the item is in the collection

Time:05-20

val map = mapOf(
    'a' to 1,
    'b' to 2,
    'c' to 3
)

val c = 'a'
if (c in map) {
    println(map[c]   1)
}

In the simple code stub, Kotlin compiler does not allow me to perform the operation in println. It yells to me with the following warning:

Operator call corresponds to a dot-qualified call 'map[c].plus(1)' which is not allowed on a nullable receiver 'map[c]'.

It drives me mad, I don't want to put !! to silence it.

CodePudding user response:

As far as Kotlin is concerned, there is no relation between c in map being true and map[c] not being null. Note that c in map is just sugar for map.contains(c), and map[c] is just sugar for map.get(c). get and contains are two separate methods, not related at all.

In the extreme case, who is to say that the map can't be modified (by another thread for example) after the in check has passed, and the c key is now gone?

If you want to use a map's value, then just access it without checking c in map. Do the null check the same way as you would for any other method that returns a nullable value. For example, you could assign it to a local val first:

val value = map[c]
if (value != null) {
    println(value   1)
}

Or use ?.let:

map[c]?.let { println(it   1) }

There are many other ways to do this, depending on what you are doing with the value exactly, but these two are the most general ones I can think of.

  • Related