我试图通过应用单个函数来考虑允许Map<String, Any?>
对象通过类型推断被视为Map<String,Any>
的函数。
我对Kotlin中的转换功能很陌生,并在地图上尝试了各种filter
和filterValues
filterNot
,如下所示:
val input = mapOf(Pair("first",null))
val filtered: Map<String,Any> = input.filter { it.value!=null }
它也无法使用任何这些
进行编译input.filterValues { it!=null }
input.filterNot { it.value==null }
input.filterNot { it.value is Nothing }
我似乎最接近的是应用多个步骤或具有未选中的强制转换警告。我原以为将值过滤为!=null
就足够了。我唯一的另一个想法是它是由于泛型?
答案 0 :(得分:8)
编译器只是不进行足够深入的类型分析来推断,例如,nums[:] = [i for i in nums if i!=val]
过滤掉地图中的input.filterValues { it != null }
值,因此生成的地图应具有非空值类型。基本上,在类型和可空性方面,可以有任意含义的任意谓词。
没有特殊情况函数可以从stdlib中的地图中过滤null
值(就像迭代物有.filterIsInstance<T>()
一样)。因此,最简单的解决方案是应用未经检查的强制转换,从而告诉编译器您确定没有违反类型安全性:
null
另请参阅:another question with a similar problem关于@Suppress("UNCHECKED_CAST")
fun <K, V> Map<K, V?>.filterNotNullValues() = filterValues { it != null } as Map<K, V>
- 请检查。
答案 1 :(得分:6)
过滤器函数返回一个与原始地图具有相同泛型类型的Map。要转换值的类型,您需要映射Any的值吗?做任何,通过做演员。编译器无法知道您传递给filter()的谓词确保过滤后的映射的所有值都是非空的,因此它不能使用类型推断。所以你最好的就是使用
val filtered: Map<String, Any> = map.filterValues { it != null }.mapValues { it -> it.value as Any }
或定义一个函数,在一次传递中进行过滤和转换,从而能够使用智能强制转换:
fun filterNotNullValues(map: Map<String, Any?>): Map<String, Any> {
val result = LinkedHashMap<String, Any>()
for ((key, value) in map) {
if (value != null) result[key] = value
}
return result
}