我提出了一个虚拟问题来说明我的观点:假设我们具有以下方便的功能来显示有关特定排序算法的信息:
fun sort(name: String, array: Array<Int>, sortingAlgorithm: (Array<Int>) -> Array<Int>) {
println(name)
sortingAlgorithm(array).forEach { print(" $it ") }
println()
}
您可以这样使用它:
sort("Selection Sort - Θ(n^2)", arrayOf(2, 3, 1), ::selectionSort)
这之所以有效是因为的签名selectionSort
很简单:fun selectionSort(array: Array<Int>): Array<Int> {
但是说我还有另一个具有以下签名的排序算法
fun quickSort(array: Array<Int>,
start: Int = 0,
end: Int = array.size - 1): Array<Int> {
最后两个参数是可选的,因此从理论上讲,您可以quickSort
按相同的方式调用selectionSort
。也就是说,它仍然尊重签名(Array<Int>) -> Array<Int>
吗?
不幸的是,当我尝试致电时,sort("Quick Sort", arrayOf(2, 3, 1), ::quickSort)
我得到:
我认为编译器不够聪明,无法意识到这两个参数是可选的。除了使sort
方法重载以接受带有签名的高阶函数以外,如何避免这个问题?
无法避免此问题,因为它会与Kotlin类型系统的2个基石相矛盾:
例如,如果您可以这样做,那么以下操作将无效,这是示例的简单重构:
val algorithm = ::quickSort
sort("Quick Sort", arrayOf(2, 3, 1), algorithm)
无论如何,sort("Quick Sort", { quickSort(unsorted) })
对于Kotlin开发人员来说,解决方法太简单了,无法花费时间在问题上。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句