首先curriedAdd
是相同的add2 _
和不是add2
。add2 只是一种方法。
scala> curriedAdd
res52: Int => (Int => Int) = <function1>
scala> add2 _
res53: Int => (Int => Int) = <function1>
关于第二个问题。我认为原因如下。正在做
scala> val i = curriedAdd(23)
i: Int => Int = <function1>
scala> i _
res54: () => Int => Int = <function0>
scala> curriedAdd(23) _
<console>:10: error: _ must follow method; cannot follow Int => Int
curriedAdd(23) _
curriedAdd(23) _
不起作用。让我们看一下 scala 手册(§6.7)-
如果 e 是方法类型或 e 是按名称调用的参数,则表达式 e _ 是格式良好的。如果 e 是带参数的方法,则 e _ 表示 e 通过 eta 扩展(第 6.26.5 节)转换为函数类型。如果 e 是 =>T 类型的无参数方法或按名称调用参数,则 e _ 表示 () => T 类型的函数,它在应用于空参数列表 () 时计算 e。
请记住,它仅评估它是方法还是按名称调用的参数。在 curriedAdd(23) _
中,它不评估 curriedAdd(23) 而是检查它是方法还是名称调用。它不是方法,也不是名称调用参数。
它不是按名称,因为按名称是变量的属性。在上面,您在评估后得到一个按名称curriedAdd(23)
参数,但curriedAdd(23)
它本身不是按名称变量。因此错误(理想情况下编译器应该已经隐藏它)。请注意,以下工作:
scala> curriedAdd(23)
res80: Int => Int = <function1>
scala> res80 _
res81: () => Int => Int = <function0>
上面的工作是因为res80 _
,在这里您正在应用_
一个按名称调用的参数,因此进行了转换。