我有这个比较排序列表的方法,并告诉你列表2中哪些项目从列表2中丢失,反之亦然,在O(N)时间内:
fun <T : Comparable<T>> compareSortedLists(
list1: Iterable<T>,
list2: Iterable<T>,
onlyInList1: MutableCollection<T>,
onlyInList2: MutableCollection<T>) {
val it1 = PeekingIterator(list1.iterator())
val it2 = PeekingIterator(list2.iterator())
while (it1.hasNext() && it2.hasNext()) {
val comp = it1.peek().compareTo(it2.peek())
if (comp < 0) // <-- ERROR: type inference failure
onlyInList1.add(it1.next())
else if (comp > 0)
onlyInList2.add(it2.next())
else {
it1.next()
it2.next() // <---- Error: type mismatch
}
}
it1.forEachRemaining { onlyInList1.add(it) }
it2.forEachRemaining { onlyInList2.add(it) }
}
IntelliJ IDEA 2018.1.4中的Kotlin编译器(1.2.41)给出了编译时错误(如上所示)。错误消息显示:
Type mismatch.
Required: Comparable<Boolean>!
Found: T!
但我不打算将if
作为表达。我的意思是它作为一个声明(编辑:我的意思是一个表达式,其值被忽略,因为所有if
实际上都是表达式)。如果我将if
转换为when
,那么它就可以编译好了:
when { // <-- Look, no error! ;-)
comp < 0 ->
onlyInList1.add(it1.next())
comp > 0 ->
onlyInList2.add(it2.next())
else -> {
it1.next()
it2.next()
}
}
为什么它认为if
是一个表达式?而且,在所有方面,为什么它认为需要Comparable<Boolean>!
?需要这种类型的上下文在哪里?
答案 0 :(得分:2)
这似乎是一个编译器错误。我在这里报道了:
https://youtrack.jetbrains.net/issue/KT-24886
这是一个最小的复制品:
fun <T : Comparable<T>> test(a: Iterable<T>) {
val x = if (booleanExpr1())
booleanExpr2()
else if (booleanExpr3())
booleanExpr4()
else {
a.iterator().next()
}
}
fun booleanExpr1() = true
fun booleanExpr2() = true
fun booleanExpr3() = true
fun booleanExpr4() = true
请注意,问题不在于&#34; if表达式不被视为语句&#34;,而是使用类型推断本身。编译器应该计算出所有then-branches的有效上限,但是失败了。