是否可以使用带有可选参数的高阶函数

时间:2017-06-20 21:00:32

标签: kotlin

我把一个虚拟问题放在一起来说明我的观点:假设我们有以下方便的功能来显示有关特定排序算法的信息:

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)时,我得到了:

type missmatch

我认为编译器不够聪明,不能意识到这两个参数是可选的。除了重载sort方法以接受具有签名的高阶函数之外,如何避免此问题?

1 个答案:

答案 0 :(得分:4)

没有避免这个问题,因为它会与Kotlin型系统的两个角落石头相矛盾:

  • 1)每个表达式都有一个类型(强类型)
  • 2)接收方不影响表达式的类型(本地推断)

例如,如果您可以这样做,以下操作就不起作用了,这是对您的示例的简单重构:

val algorithm = ::quickSort
sort("Quick Sort", arrayOf(2, 3, 1), algorithm)

无论如何,sort("Quick Sort", { quickSort(unsorted) })解决方法对于Kotlin开发人员来说太简单了,不能花时间在这个问题上。