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

Intellij idea 我可以使用lambda的名称作为传递的参数吗;括号外“;?,intellij-idea,lambda,functional-programming,kotlin,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(

我可以在括号外写一个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
将名称放在那里(括号外)的语法是什么


我不知道为什么,但在报纸上没有一个关于这个主题的词。它说我们可以把lambda放在那里,但不能用一个词来描述表示lambda的变量或常量。

将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))

将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))
我不知道为什么,但是在文档中没有一个关于这个主题的词

是的,有:

在Kotlin中,有一种约定,即如果函数的最后一个参数是函数,,并且将lambda表达式作为相应的参数传递,则可以在括号外指定它

plus3
是一个标识符,而不是lambda表达式,因此不能在括号外指定它

plus3的类型是(Int,Int,Int->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将起作用。但事实并非如此

我不知道为什么,但是在文档中没有一个关于这个主题的词

是的,有:

在Kotlin中,有一种约定,即如果函数的最后一个参数是函数,,并且将lambda表达式作为相应的参数传递,则可以在括号外指定它

plus3
是一个标识符,而不是lambda表达式,因此不能在括号外指定它

plus3的类型是(Int,Int,Int->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将起作用。但事实并非如此。

那是因为你不能。这是因为没有理由:/@OliverCharlesworth替换是最基本的逻辑规则。名称理论高于逻辑。如果有违反,则应解释该案例,并采用更具体的规则。对话“为什么?-因为!”甚至对于儿童游戏来说都不有趣。答案中已经解释过,医生说你需要提供一个lambda表达式,所以没有歧义。我也给了你一个理由——没有令人信服的理由允许这样做。你还需要什么?@OliverCharlesworth我需要为一个项目选择语言。我认为科特林是个骗子。但正如我所看到的,Java或Groovy函数式编程更为一致。没有任何客观原因的禁止将导致错误和误解。@Gangnus如果这是你所关心的,Java当然也不例外。例如,“如果程序中的lambda表达式发生在赋值上下文(§5.2)、调用上下文(§5.3)或强制转换上下文(§5.5)以外的地方,则为编译时错误。”。像
plus3
这样的变量在其他上下文中也有效。这是因为您不能。这是因为没有理由:/@OliverCharlesworth替换是最基本的逻辑规则。名称理论高于逻辑。如果有违反,则应解释该案例,并采用更具体的规则。对话“为什么?-因为!”甚至对于儿童游戏来说都不有趣。答案中已经解释过,医生说你需要提供一个lambda表达式,所以没有答案