How to use withDefault wrappers?

时间:2016-04-25 09:33:19

标签: kotlin

I want to use MutableMap with defaults:

val myMap = mutableMapOf<String, Set<String>>().withDefault { mutableSetOf() }

but I can't use getOrImplicitDefault method because withDefault returns MutableMap<String, Set<String>> type. Moreover, I can't cast to MutableMapWithDefault interface because this is a private interface.

I can't use get method either because it returns a nullable type. It is ok because this is a method on the MutableMap interface (moreover it doesn't call defaultValue callback for take default value).

Seems like this functionality is not correctly implemented in Kotlin, or I am using it wrong. So, how do I use withDefault wrappers correctly?

6 个答案:

答案 0 :(得分:7)

从Kotlin 1.0开始,withDefault返回的包装器仅在属性委派用例中可用。

val map = mutableMapOf<String, Set<String>>().withDefault { mutableSetOf() }

var property: Set<String> by map // returns empty set by default

答案 1 :(得分:5)

在Kotlin 1.1中,如果您使用getValue()函数而不是get()函数,这实际上是有效的。

答案 2 :(得分:1)

好吧,getOrImplicitDefault的所有实现都将t重定向到getOrElseNullable。也许试试吧。

答案 3 :(得分:1)

我一直在寻找一种从MutableMap返回默认值的方法,但也会同时存储它以供将来检索。 .withDefault仅返回默认值,但不存储它。每次需要检索值时调用.getOrPut都不是一个好主意。我想出了类似的东西:

val myMap = with(mutableMapOf<String, Set<String>>()) {
    withDefault { key -> getOrPut(key, { mutableSetOf<String>() }) }
}

这将在支持MutableMap对象的getOrPut包装器内调用withDefault,该对象将缺少的键值对放入地图并返回它。

答案 4 :(得分:0)

使用以下方法:

myMap.getOrPut(someKey,{DEFAULT_VALUE})

文档:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/get-or-put.html

答案 5 :(得分:0)

Map withDefault返回只读映射的包装,具有指定函数defaultValue提供的隐式默认值。当原始地图不包含指定键的值时,将使用此隐式默认值。同时查看getOrElsegetOrDefault的用法,其用法与列表相同-

val emojiMap = mapOf("Grinning Face" to "?", "Winking face" to "?", 
                "Zany face" to "?").withDefault({"?"})

fun main()
{
    println(emojiMap) // {Grinning Face=?, Winking face=?, Zany face=?}
    println(emojiMap.getValue("Grinning Face")) // ?
    println(emojiMap.getValue("Zany face")) // ?
    println(emojiMap.getValue("Smiling face")) // ?

    // getOrElse & getOrDefault
    println(emojiMap.getOrElse("Flushed face"){"?"}) // ?
    println(emojiMap.getOrDefault("Sad face","?")) // ?
}