Kotlin docs表示支持higher-order functions。当将顶级函数作为参数传递时,为什么语言甚至需要::function
语法?
鉴于:
fun isOdd(x: Int) = x % 2 != 0
val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd)) // here.
为什么不
fun isOdd(x: Int) = x % 2 != 0
val numbers = listOf(1, 2, 3)
println(numbers.filter(isOdd)) // simple and makes more sense
有关function reference syntax here的更多信息。
答案 0 :(得分:6)
因为Java(以及Kotlin)对字段和方法使用单独的命名空间,所以需要::
来避免歧义。例如:
val isOdd : (Int) -> Boolean = { x -> x % 2 != 0 }
fun isOdd(x: Int): Boolean {
return x % 2 != 0
}
val odds = listOf(1,2,3).filter(isOdd) // uses the val version
val otherOdds = listOf(1,2,3).filter(::isOdd) // uses the fun version
答案 1 :(得分:6)
Kotlin语言设计试图避免模糊的情况,其中某些东西的缺失可能同时是正确的和不正确的语法。例如,如果您允许使用建议的语法:
isOdd // error, function invocation expected isOdd(...)
isOdd // not error, you have a function reference
::
是关于意图的明确信号。因此,isOdd
案例只会出现错误,因为您现在有可能不重叠:
isOdd // error, function invocation expected isOdd(...)
::isOdd // function reference
isOdd() // error, missing parameter x
isOdd(x) // function call
这就是Kotlin避免导致模糊状态的原因。您的眼睛也可以快速解决问题,就像IDE和静态分析一样,就像编译器一样。如果你开始允许这种更宽松的语法,你将开始遇到复杂的歧义,例如当使用中缀函数等时。语言设计比#34更复杂哦,让我们让它们输入更少的字符"因为复杂性矩阵比你想象的要大得多,如果你只看一个忽略所有其他用例的用例。
为什么上面接受的答案不正确:
目前接受的答案是这是一个命名空间问题,这是不正确的。在该样本中,他们使用:
val isOdd : (Int) -> Boolean = { x -> x % 2 != 0 }
并声称由于命名空间而无法使用::
。它实际上是有效的,因为它已经是一个函数引用并被声明为作为函数引用,因此不需要运算符使其成为函数引用。但是,该功能不是参考。这是一个功能。它需要一个运算符::
将其转换为对函数的引用,这是将filter
方法用作谓词时所需的函数。
该答案中的主张具有误导性和不真实性。