我可以在括号外写一个lambda表达式,但我不能把它放在那里。我尝试了很多方法:
val plus3: (Int,Int,Int)->Int = {a,b,c->a+b+c}
println(apply3(1,2,3){a,b,c->a+b+c}) // OK
println(apply3(1,2,3){plus3}) // Type mismatch. Required: Int, Found: (Int,Int,Int)->Int
println(apply3(1,2,3){(plus3)}) // Type mismatch. Required: Int, Found: (Int,Int,Int)->Int
println(apply3(1,2,3)plus3) // unresolved reference
println(apply3(1,2,3){plus3()}) // value captured in a closure
println(apply3(1,2,3){(plus3)()}) // value captured in a closure
在那里放置名称的语法是什么(括号外)?
我不知道为什么,但在documentation中,主题上没有一个词。它说我们可以把lambda放在那里,但不能说一个关于表示lambda的变量或常量。
答案 0 :(得分:4)
我不知道为什么,但在文档中没有关于主题的话。
是的,有:
在Kotlin中,有一个约定,如果函数的最后一个参数是一个函数,并且你传递一个lambda表达式作为相应的参数,你可以在括号之外指定它< / p>
plus3
是标识符而不是lambda表达式,因此您不能在括号外指定它。
plus3的类型是(Int,Int,Int-&gt; Int)。与{a,b,c-> a + b + c}相同。再看一下我从Kotlin编译器获得的消息。
您是指通过{ plus3 }
时的错误消息?通过Kotlin规则{ plus3 }
是一个lambda,忽略它的参数(如果有的话)并返回plus3
。因此规则适用,apply3(1,2,3){plus3}
与apply3(1,2,3,{plus3})
相同。
它将plus3视为Int。
恰恰相反:它希望看到Int
作为lambda的返回值,并看到plus3
(Int,Int,Int) -> Int
。
所以,这里的问题不是高度的哲学性质,而是纯粹的句法。
这正是我的观点:规则纯粹是语法规则,它是在编译器知道plus3
的类型或值之前应用的,因此它不知道或不关心这个值是否恰好是lambda 。
规则可以代替
在Kotlin中,有一个约定,如果函数的最后一个参数有一个函数类型,你可以在括号外指定它
在这种情况下apply3(1,2,3) plus3
可行。但事实并非如此。
答案 1 :(得分:2)
将lambda表达式放在函数调用的括号之外与将它放在括号中是一样的:
println(apply3(1, 2, 3, { a, b, c -> a + b + c }))
从这里开始,我们可以简单地将lambda分配给val
(就像你所做的那样),结果是:
val plus3: (Int, Int, Int) -> Int = { a, b, c -> a + b + c }
println(apply3(1, 2, 3, plus3))