为什么Kotlin需要函数参考语法?
Kotlin docs表示支持高阶函数 。 为什么在将顶级函数作为参数传递时,语言甚至需要一个::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
更多关于这里的函数参考语法 。
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和静态分析一样,你的眼睛也可以快速地找到问题,就像编译器一样。 如果你开始允许这种宽松的语法,你将开始遇到复杂的模糊,比如当作为中缀函数使用时等等。 语言设计比“哦,让我们让他们输入更少的字符”更复杂,因为复杂度矩阵比你想象的要大得多,如果你只看一个用例而忽略所有其他用例。
为什么上面接受的答案是不正确的:
目前接受的答案是这是一个命名空间问题,这是不正确的。 在这个例子中,他们使用:
val isOdd : (Int) -> Boolean = { x -> x % 2 != 0 }
并声称它没有::
因为命名空间的作品。 它实际上工作,因为这已经是一个函数引用 ,并被声明为一个函数引用 ,因此不需要一个运算符使其成为函数引用 。 但是,函数不是一个参考。 这是一个功能。 它需要一个运算符::
将其转换为函数的引用,这是使用它作为filter
方法的谓词所需要的。
答案中的主张是误导和不实的。
因为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