所以你需要知道很多事情才能真正理解这个问题的答案。
在 Scala 中,任何def 都是method,它只不过是一些object 的成员之一。 methods 不是 Scala 中的一等成员,这也意味着 methods 不能单独存在。
在 Scala 中,任何事物的 value 都必须是 expression。这意味着def 的 RHS 必须是类似def abc = some-expression 的表达式。表达式示例有1、1 + 1、"xyz"、anotherMethodCallWhichWillReturnAnExpression() 等。
像def abc = xxxxxx 这样的东西在Scala 语言定义中不是expression。因此你不能这样做,
def prodC1(f : Int => Int) : (Int, Int) => Int = {
def prodA1(a : Int, b : Int) : Int =
if(a > b) 1 else f(a) * prodA1(a+1, b)
}
现在,当您添加带有prodA1 的额外行时,您是在告诉Scala 返回您刚刚定义的prodA1。但请记住,prodA1 只是一个 method,因此不能单独存在,因此实际上无法返回。
但functions 是 Scala 中的第一类成员(表示为各种 FunctionX 类之一的实例),因此可以返回。
在这种情况下,Scala 会智能地将这个method 提升为function 类型为(Int, Int) => Int。这称为 eta 扩展。
更详细地了解事物。您可以打开 Scala 控制台并尝试以下操作。
scala> val s = "abc"
// s: String = abc
scala> val i = 10
// i: Int = 10
scala> def prodA1(a : Int, b : Int) : Int = if (a > b) 1 else a * prodA1(a+1, b)
// prodA1: (a: Int, b: Int)Int
注意实际values 和def 的Scala 控制台输出之间的差异。现在,如果我尝试将prodA1 用作value 的val,我将收到以下错误。
scala> val x = prodA1
// <console>:12: error: missing argument list for method prodA1
// Unapplied methods are only converted to functions when a function type is expected.
// You can make this conversion explicit by writing `prodA1 _` or `prodA1(_,_)` instead of `prodA1`.
// val x = prodA1
Scala 告诉您,您可以使用_ 将method 显式转换为function。让我们试试吧。
scala> val x = prodA1 _
// x: (Int, Int) => Int = $$Lambda$1077/293669143@13278a41
现在x 是function 类型的(Int, Int) => Int。
另外,第一行 Unapplied methods are only converted to functions when a function type is expected. 告诉您您的案例中实际发生的情况。
由于预计prodC1 会返回(Int, Int) => Int 类型的function,并且您提供了prodA1,因此Scala 使用eta-expansion 自动将您的method 转换为function。