Kotlin Map非空值

假设我有一张地图将一张纸牌的字母翻译成一个整数

val rank = mapOf("J" to 11, "Q" to 12, "K" to 13, "A" to 14) 

在使用地图时,即使Map和Pair是不可变的,我总是必须做一个空的安全检查:

 val difference = rank["Q"]!! - rank["K"]!! 

我猜这是来自genericstypes有没有? 超types。 为什么不能在编译时解决Map和Pair是不可变的问题?

这不是关于Map的实现(是基于Kotlin还是基于Java的)。 您正在使用Map,并且地图可能没有关键字,因此[]运算符返回可为空的types。

mapOf()提供了一个Map,并不保证key的存在 – 这是一种特别考虑Map的Java实现的期望。

虽然我个人更喜欢坚持使用无效调用和elvis操作符,但是听起来像在调用站点上更喜欢更干净的代码(尤其是考虑到您知道这些键存在且具有关联的非空值)。 考虑一下:

 class NonNullMap(private val map: Map) : Map by map { override operator fun get(key: K): V { return map[key]!! // Force an NPE if the key doesn't exist } } 

通过委托给map的实现,但是重写get方法,我们可以保证返回值是非空的。 这意味着您不再需要担心!!,?,或?:您的用例。

一些简单的测试代码显示这是真的:

 fun main(args: Array) { 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  nonNullMapOf(vararg pairs: Pair) = NonNullMap(mapOf(*pairs))