以下内容:
val add = (a: Int, b: Int) => a + b
转换为:
object add extends Function2[Int, Int, Int] {
def apply(a: Int, b: Int) = a + b
}
,而
val a1 = add(_: Int, 3)
转换为:
object a1 extends Function1[Int, Int] {
def apply(x: Int): Int = {
add(x, 3)
}
}
但是当我这样做时:
scala> val a2 = add _
a2: () => (Int, Int) => Int = <function0>
然后调用a2
,它会抛出错误:
scala> a2(1, 2)
<console>:11: error: too many arguments for method apply: ()(Int, Int) => Int in trait Function0
a2(1, 2)
^
这是为什么?为什么以下工作?
a2()(1, 2)
答案 0 :(得分:9)
add
已经是Function2[Int, Int, Int]
。如果您希望a2
具有相同的类型,那么简单的赋值就足够了。
scala> val a2 = add
a2: (Int, Int) => Int = <function2>
scala> a2(1, 2)
res3: Int = 3
您正在考虑的是将方法扩展为函数。如果我们有:
def add(a: Int, b: Int): Int = a + b
然后,我们会使用add _
来获取eta-expansion以赋值。
scala> def a2 = add _
a2: (Int, Int) => Int
scala> a2(1, 2)
res4: Int = 3
但是add
已经一个函数,因此下划线具有不同的含义。 add
现在是值,而不是方法。由于add
是值,因此它类似于无参数方法,它返回Function2[Int, Int, Int]
。如果我们尝试对其进行eta扩展,我们会得到() => Function2[Int, Int, Int]
。
考虑一个简单的例子,我们有一个简单的val a = 1
。 a
与返回1
(def a = 1
)的无参数方法基本相同。如果我尝试获得eta扩展,我将获得() => Int
。
scala> val a = 1
a: Int = 1
scala> val a2 = a _
a2: () => Int = <function0>