Как использовать с оберткамиDefault?
Я хочу использовать MutableMap
с настройками по умолчанию:
val myMap = mutableMapOf<String, Set<String>>().withDefault { mutableSetOf() }
но я не могу использовать метод getOrImplicitDefault
, потому что withDefault
возвращает тип MutableMap<String, Set<String>>
. Более того, я не могу использовать интерфейс MutableMapWithDefault
, потому что это частный интерфейс.
Я не могу использовать метод get
либо потому, что он возвращает тип с нулевым значением. Это нормально, потому что это метод на интерфейсе MutableMap
(более того, он не вызывает обратный вызов defaultValue
для получения значения по умолчанию).
Похоже, эта функциональность неправильно реализована в Котлине, или я неправильно ее использую. Итак, как правильно использовать обертки withDefault
?
Ответы
Ответ 1
Начиная с Kotlin 1.0, оболочка, возвращаемая withDefault
может использоваться только в случаях использования делегирования свойства.
val map = mutableMapOf<String, Set<String>>().withDefault { mutableSetOf() }
var property: Set<String> by map // returns empty set by default
Ответ 2
Похоже, что в Kotlin 1.1 это действительно работает, если вы используете функцию getValue() вместо функции get()
.
Ответ 3
Ну, все реализации getOrImplicitDefault
перенаправляют t на getOrElseNullable
. Возможно, попробуйте это.
Ответ 4
Я искал способ вернуть значение по умолчанию из MutableMap, но в то же время сохранить его для последующего извлечения. .withDefault
только возвращает значение по умолчанию, но не сохраняет его. Вызов .getOrPut
каждый раз, когда мне нужно получить значение, не выглядит хорошей идеей. Я придумал что-то вроде этого:
val myMap = with(mutableMapOf<String, Set<String>>()) {
withDefault { key -> getOrPut(key, { mutableSetOf<String>() }) }
}
Это вызывает getOrPut
в withDefault
для резервного объекта MutableMap, который помещает отсутствующую пару ключ-значение в карту и возвращает ее.
Ответ 5
Используйте следующий метод:
myMap.getOrPut(someKey,{DEFAULT_VALUE})
Документация: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/get-or-put.html