为什么Kotlin不能推断比较器的类型?

10
阅读有关SAM转换的Java互操作文档后,我期望Kotlin函数可以使用lambda函数而无需显式指定参数作为Comparator。然而,以下代码出现了“类型推断失败”:Collections.sortWith(comparator: kotlin.Comparator<in T> /* = java.util.Comparator<in T> */)
val someNumbers = arrayListOf(1, 5, 2)
someNumbers.sortWith({ x, y -> 1 })

鉴于:

val someNumbers = arrayListOf(1, 5, 2)
someNumbers.sortWith(Comparator { x, y -> 1 })

编译并正确运行


3
有趣的是,Collections.sort(arrayList, { x, y -> 1 }) 是可行的。 - leonardkraemer
1
如果sortWith接受一个类型为comparator: (T, T) -> Int的比较器,那么就不需要指定Comparator了...但是我现在不知道该怎么处理这个信息;-) 而且那样其实也帮不上太多忙,因为我们在sortedWith中仍然需要使用Collections.sort.(this) { x, y -> comparator(x, y) }。(我只是在胡思乱想) - Roland
非常有趣的阅读:Kotlin问题#7770-Kotlin类的SAM,也许值得点赞;-) 另外:#11129 Kotlin函数的SAM转换...也许在1.3版本中会有所改进...尽管我还没有看到... - Roland
1个回答

6
阅读了Kotlin问题“Kotlin类的SAM”的评论后,我对SAM转换以及为什么引入typealias有了更深入的了解,但尚未了解为什么尚未解决这个特定的行为问题......而且像问题和它的评论所显示的那样,我不是唯一一个遇到这个问题的人。

总结一下,SAM转换仅适用于Java接口(也可以参考this comment)。JetBrains正在进行或需要进行更大的重构,并尝试解决这个问题,以便SAM也可用于Kotlin函数本身(也可以参考this comment)。 他们正在尝试支持在单独的问题中对Kotlin函数进行SAM转换, 这可能会随着1.3版发布。目前我正在测试1.3:我还没有看到任何关于这个问题的信息。因此,如果您像我一样喜欢SAM转换,您可以选择升级Kotlin类的SAMKotlin函数的SAM转换或两者兼备。

顺便说一下:Ilya Gorbunov也使用了非常类似的例子,使用arrayOf().sort

2
不错的发现。我最喜欢的部分是“由于缺乏此功能,我不得不在我的Kotlin项目中创建Java接口。” https://youtrack.jetbrains.com/issue/KT-7770#focus=streamItem-27-2214344-0-0 所以至少对于你自己的代码来说,有一个解决方法。 - leonardkraemer
说实话,我宁愿不使用变通方法生活;-) 如果我们有“漂亮的函数类型”,我真的不明白为什么sortWith要使用Comparator参数...在这种特定情况下,我可能更愿意使用sort(someNumbers) { x, y -> 1 }Collections.sort导入...它更短,易读,并且允许我使用SAM转换。 - Roland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接