是否有可能使用具有可选参数的高阶函数

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

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一样调用quickSort 。 也就是说,它遵守签名(Array<Int>) -> Array<Int> Right?

不幸的是,当我尝试调用sort("Quick Sort", arrayOf(2, 3, 1), ::quickSort)我得到:

类型错配

我认为编译器没有足够的智能来认识到这两个参数是可选的。 如何避免这个问题,除了重载sort方法来接受带签名的高阶函数呢?

有没有避免这个问题,因为它会克服Kotlin类型系统的两个角落石头:

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

例如,如果你可以做到这一点,以下将无法工作,这是你的例子的一个简单的重构:

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

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