这不是关于如何做到这一点的问题,而是关于其背后推理的问题。我已经搜索了SO,Kotlin文档和googs以找到为什么Kotlin人以这种方式完成他们的语法但却无法真正理解它。所以我希望有一个聪明的人可以帮助我。
鉴于:
private fun printResult(function: (Int, Int) -> Int, a: Int, b: Int) {
我明白了:
"function: (Int, Int)"
意味着这是我们传入的函数,其签名需要两个Int参数。
此外,我明白了:
"-> Int"
表示此函数返回Int
最后,我明白了:
"a: Int, b: Int"
是正常的参数/参数列表,这是我们收到实际参数的地方。
但它对我来说似乎很笨拙。
为什么要给签名带来麻烦:
"(Int, Int) -> Int"
然后坚持再次重复这些论点:
"a: Int, b: Int"
但是,如果你必须这样做,那么,但为什么不为了清晰起见重复返回,以便它是这样的:
"private fun printResult(function: (Int, Int) -> Int, a: Int, b: Int): Int"
甚至:
"private fun printResult(function: (a: Int, b: Int) -> Int) {"
似乎不清楚的语法与重复不需要在那里和/或可能不清楚的签名,因为你的功能变得更复杂。
我错过了什么?
谢谢
在Forpas和Abib的解释之后的例子 - 为了清楚任何像我一样思考的人:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
printResult(::add, 4, 2)
printResult(::subtract, 4, 2)
}
private fun add(a: Int, b: Int): Int {
return a + b
}
private fun subtract(a: Int, b: Int): Int {
return a - b
}
private fun printResult(passedInFunction: (someInt: Int, anotherInt: Int) -> Int, a: Int, b: Int) {
// Simply takes the values of "a" and "b" and does whatever
// the latest version of the "passedInFunction" is set up to do.
// It does this by passing the arguments that were given to
// "printResult" into whatever the current version of "passedInFunction" is.
val result = passedInFunction(a, b)
println("result: $result")
// Manipulates the values from the arguments passed into
// "printResult" and passes the result into "passedInFunction"
// as parameters/arguments.
println("function: " + passedInFunction(a - b, a + b))
}
让我们说这是printResult
函数:
fun printResult(function: (Int, Int) -> Int, a: Int, b: Int) {
println(function(a - b, a + b))
}
我们还定义了multiply
函数,该函数具有function
的printResult
参数的签名:
fun multiply(x: Int, y: Int) = x * y
现在你可以这样调用printResult
:
printResult(this::multiply, 5, 3)
它会打印:
16
你可以看到a
的参数b
和printResult
不是function
的论据。
事实上,他们甚至根本不会被用来计算function
的论据。
所以没有以下情况:
语法不清晰,重复不需要存在和/或可能存在不明确的签名
a
和b
是printResult
函数的参数,而不是参数中的function
。所以printResult
有3个参数,一个函数,a
和b
,所以设计这个函数的人决定它需要2个参数(a和b)和一个将两个Int
s转换成另一个Int
的函数。
另一方面(作为一般提示),lambdas的参数也可以命名,因此printResult(function: (someInt:Int, anotherInt:Int)->Int, a:Int, b:Int)
也有效(当使用此函数时,它也有助于IDE代码完成)
另外,根据Kotlin文档,最好将lambda / function参数作为最后一个(所以上面的例子变成了private fun printResult(a: Int, b: Int, function: (Int, Int) -> Int)
),因为在这种情况下,它可以这样使用:
printResult(1,2) { firstInt, secondInt -> ///