Kotlin操作值为MutableList的Map时空安全与类型报错问题
第一个问题原因:访问Map值必须加
!!的本质 Kotlin中Map的get运算符(也就是[key]写法)的返回值从定义上就是可空类型V?:
- 类型系统不会做跨逻辑的流分析,哪怕你是遍历
myStringMap.keys拿到的key,编译器也无法静态证明这个key一定存在于Map中,自然不会把返回值推断为非空类型。 - 从业务逻辑上你当然知道遍历keys拿到的key肯定存在,但这个判断不在编译器的类型校验规则内,所以拿到的值类型是
MutableList<String>?,直接调用add就会触发可空检查提示。 - 不想写非空断言的话可以替换为
myStringMap.getValue(key),这个方法在key不存在时会直接抛异常,返回值是非空类型,和你当前的逻辑预期完全匹配。
第二个问题原因:过滤后取值依然报可空类型错误
首先纠正一个误区:
- 过滤操作返回的
it确实是Map<Int, MutableList<String>>类型,你的判断没有错。 - 这个报错和
MutableList要不要转List没有任何关系,根源还是Map的取值规则:不管Map做过什么过滤、是什么类型,只要用[key]的方式取值,返回值永远是可空的V?。编译器不会因为你遍历的是当前Map的keys,就自动推断这个key一定存在、对应值非空。
解决方式非常简单,不要遍历keys再二次通过key取值,直接遍历Map的entries即可,拿到的value本身就是非空类型,不需要额外做可空处理:
myStringMap.filter { (_, value) -> value.isNotEmpty() }.forEach { (_, value) -> val bytes = GetBytes(value) allBytes.add(bytes) }
额外提一句:你一开始用mapOf创建的是只读Map,如果后续需要对Map本身增删键值对,要替换为mutableMapOf,如果只是修改Map中存储的MutableList内部元素,当前写法不会有问题。
内容的提问来源于stack exchange,提问作者JPV
相关产品推荐
相关产品推荐

