下面的代码无法编译,并出现以下错误:
Error:(28, 61) Type mismatch: inferred type is String but Nothing was expected
我不清楚为什么会这样。我想要达到的目的是让filterMap
采取任何类型的过滤器并将其应用于传入的数据。正如您从用于测试的数组中看到的:arrayListOf("Message1", 1, 'C')
。反正有实现这一目标的方法吗?我可以通过指定MutableMap<Filter<Any>, String>
来解决它,但这意味着我的过滤器也必须是(Any) -> Boolean
class Filter<Q> (val predicate: (Q) -> Boolean, val isEnabled: Boolean) {
constructor(predicate: (Q) -> Boolean) : this(predicate, false)
override fun equals(other: Any?): Boolean {
if (other == null || other !is Filter<*>) {
return false
}
return isEnabled == other.isEnabled && predicate == other.predicate
}
override fun hashCode(): Int {
return 0x31 xor predicate.hashCode() xor isEnabled.hashCode()
}
}
val filterMap: MutableMap<Filter<*>, String> = HashMap()
fun main(args: Array<String>) {
val messages = arrayListOf("Message1", 1, 'C')
val isMessage1: (String) -> Boolean = { it == "Message1" }
val isMessage1Filter = Filter(isMessage1)
filterMap.put(isMessage1Filter, "Matched Message1")
messages.forEach { message ->
filterMap.filterKeys { it.isEnabled || (it.predicate(message)) }
.forEach {
it.value.forEach {
println(it)
}
}
}
}
答案 0 :(得分:2)
过滤器的定义为星形投影:Filter<*>
,当您从地图上获取函数时,该函数会生成函数(Nothing) -> Boolean
:
val pred = it.predicate //inferred type: (Nothing) -> Boolean
这就是为什么编译器不接受String
作为参数。
此外,您的messages
的类型为ArrayList<Any>
,您不能仅将它们用作String
。
科特林是一种静态类型的语言,它将不允许这些不安全的尝试。
要解决此问题,您可以将所有内容更改为String
个泛型:
val filterMap: MutableMap<Filter<String>, String> = mutableMapOf()
val messages = listOf("Message1")
我知道,这不会满足您的需要,因为您正在寻找通用解决方案。但是随后,您将不得不找到一种方法来安全地投射从非特定集合中获取的实体。