Tom*_*son 10 collections kotlin
假设我有一张Map用于将扑克牌的字母翻译成整数
val rank = mapOf("J" to 11, "Q" to 12, "K" to 13, "A" to 14)
Run Code Online (Sandbox Code Playgroud)
使用地图时,即使Map和Pair是不可变的,我也总是必须进行空安全检查:
val difference = rank["Q"]!! - rank["K"]!!
Run Code Online (Sandbox Code Playgroud)
我想这是因为泛型类型有Any吗?超类型.当Map和Pair都是不可变的时,为什么不能在编译时解决这个问题呢?
Nur*_*lan 19
fun <K, V> Map<K, V>.getValue(key: K): V
Run Code Online (Sandbox Code Playgroud)
throws NoSuchElementException - 当映射不包含指定键的值并且没有为该映射提供隐式默认值时。
但是get == map[] 的 运算符返回 nullable。
operator fun <K, V> Map<out K, V>.get(key: K): V?
Run Code Online (Sandbox Code Playgroud)
mapOf()提供的Map不能保证键的存在 - 特别是考虑到Map的Java实现,这是一种预期的东西.
虽然我个人可能更喜欢坚持使用零安全呼叫和elvis运营商,但听起来你更喜欢在呼叫站点使用更干净的代码(特别是考虑到你知道这些密钥存在且具有相关联的非空值).考虑一下:
class NonNullMap<K, V>(private val map: Map<K, V>) : Map<K, V> by map {
override operator fun get(key: K): V {
return map[key]!! // Force an NPE if the key doesn't exist
}
}
Run Code Online (Sandbox Code Playgroud)
通过委托map的实现,但是重写get方法,我们可以保证返回值是非null的.这意味着您不再需要担心!!,?.或?:用于您的用例.
一些简单的测试代码表明这是真的:
fun main(args: Array<String>) {
val rank = nonNullMapOf("J" to 11, "Q" to 12, "K" to 13, "A" to 14)
val jackValue: Int = rank["J"] // Works as expected
println(jackValue)
val paladinValue: Int = rank["P"] // Throws an NPE if it's not found, but chained calls are considered "safe"
println(jackValue)
}
// Provides the same interface for creating a NonNullMap as mapOf() does for Map
fun <K, V> nonNullMapOf(vararg pairs: Pair<K, V>) = NonNullMap(mapOf<K, V>(*pairs))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6430 次 |
| 最近记录: |