Обозначение в скобках на карте карты в Котлине - PullRequest
0 голосов
/ 29 октября 2019

В Kotlin можно использовать скобочную запись с картой, поэтому следующий код:

  val mapOfMap: Map<String, Map<String, String>> = mapOf("Key1" to mapOf("Subkey1" to "Value1", "Subkey2" to "Value2"))
  println(mapOfMap["Key1"])

печатает:

{Subkey1=Value1, Subkey2=Value2}

Это здорово. Но почему я не могу сделать следующее

println(mapOfMap["Key1"]["Subkey1"])

Это вызывает ошибку компиляции: Разрешены только безопасные (?.) Или ненулевые утвержденные (!!.) Вызовыобнуляемый приемник типа Map?

Как правильно обращаться с этим?

Ответы [ 2 ]

3 голосов
/ 30 октября 2019

mapOfMap["Key1"] возвращает Map<String, String>?, а оператор get для nullable Map не указан. Поэтому следующий код не компилируется:

mapOfMap["Key1"]["Subkey1"]

Вы можете скомпилировать его, создав функцию расширения get operator с обнуляемым Map получателем:

operator fun <K, V> Map<K, V>?.get(key: K): V? = this?.get(key)

Вы также можете создать расширение get operator для карт карт:

operator fun <K1, K2, V> Map<K1, Map<K2, V>>.get(key1: K1, key2: K2): V? = get(key1)?.get(key2)

И использовать его следующим образом:

mapOfMap["Key1", "Subkey1"]
3 голосов
/ 29 октября 2019

Потому что mapOfMap["Key1"] может возвращать ноль, поскольку не может угадать, находится ли нужный ключ на карте или нет. Это то же самое, что звонить mapOfMap.get("Key1"). Вторая карта может быть нулевой, поэтому она не может вызвать другую .get() для нее. Вы можете сделать это вместо: mapOfMap["Key1"]?.get("Subkey1")

...