Reputation: 2083
In Kotlin it is possible to use bracket notation with a Map, so the following code:
val mapOfMap: Map<String, Map<String, String>> = mapOf("Key1" to mapOf("Subkey1" to "Value1", "Subkey2" to "Value2"))
println(mapOfMap["Key1"])
prints:
{Subkey1=Value1, Subkey2=Value2}
That's great. But why can't I do the following
println(mapOfMap["Key1"]["Subkey1"])
It causes a compilation error: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Map?
What is the proper way to handle this?
Upvotes: 1
Views: 2131
Reputation: 2492
mapOfMap["Key1"]
returns Map<String, String>?
, and get
operator isn't specified for nullable Map
. Therefore, the following code does not compile:
mapOfMap["Key1"]["Subkey1"]
You can make it compile by creating extension get
operator
function with nullable Map
receiver:
operator fun <K, V> Map<K, V>?.get(key: K): V? = this?.get(key)
You can also create an extension get
operator
function for maps of maps:
operator fun <K1, K2, V> Map<K1, Map<K2, V>>.get(key1: K1, key2: K2): V? = get(key1)?.get(key2)
And use it this way:
mapOfMap["Key1", "Subkey1"]
Upvotes: 3
Reputation: 821
Because mapOfMap["Key1"]
could return null, since it cannot guess if the desired key is in the map or not. It's the same as calling mapOfMap.get("Key1")
. The second map can be null, thus it cannot call another .get()
on it. You can do this instead: mapOfMap["Key1"]?.get("Subkey1")
Upvotes: 5