Как использовать с обертками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, который помещает отсутствующую пару ключ-значение в карту и возвращает ее.