我可以使用lambda的名称作为“在括号外”传递的参数吗?

时间:2017-12-22 00:14:30

标签: intellij-idea lambda functional-programming kotlin

我可以在括号外写一个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的变量或常量。

2 个答案:

答案 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))