Scala 理解咖喱鳞片
我觉得我不太懂咖喱。在第一条语句中,我们在不带参数的情况下调用Scala 理解咖喱鳞片,scala,Scala,我觉得我不太懂咖喱。在第一条语句中,我们在不带参数的情况下调用sumCubes,因此sum将以匿名函数作为参数进行调用,并返回一个function2 在第二次和第三次调用中到底发生了什么, 为什么我们能做到 def sum(f: Int => Int): (Int, Int) => Int = { def sumF(a: Int, b: Int): Int = if (a > b) 0 else f(a) + sumF(a + 1, b)
sumCubes
,因此sum
将以匿名函数作为参数进行调用,并返回一个function2
在第二次和第三次调用中到底发生了什么,
为什么我们能做到
def sum(f: Int => Int): (Int, Int) => Int = {
def sumF(a: Int, b: Int): Int =
if (a > b) 0
else f(a) + sumF(a + 1, b)
sumF
}
def sumCubes = sum(a => a * a * a)
sumCubes // output Function2
sumCubes(1,10) // output 3025.
sumCubes() // doesn't work
但不是
sum(a => a * a * a)(1,10)
我的理解是,在sum(a=>a*a*a)(1,10)
中,我们部分地将sum
应用于匿名函数,该匿名函数返回一个函数2,该函数应用于第二对参数(1,10),因此我们得到3025
但是,在sumCubes()(1,10)
的情况下也应该发生同样的情况,首先调用sumCubes
而不带参数,然后使用匿名函数调用sum
,返回的函数2将应用于(1,10)
为什么
sumCubes(1,10)
可以工作,但不sumCubes()(1,10)
,那么sumCubes
和sumCubes()
不应该意味着同样的事情,调用函数sumCubes
。另外,如果一个简单引用sumCubes
正在调用它,我如何传递它。我觉得我没有理解Scala的一些基本知识。Scala的方法可以有多个参数列表
例如,这里有一个方法foo
,它有十个参数列表,其中前七个是空的:
sumCubes()(1,10)
您可以按如下方式调用它:
def foo()()()()()()()(a: Int)(b: Int)(c: Int): Int = a + b + c
def bar(i: Int)(f: Int => Int) = f(i)
它将打印321
请注意,在调用方法时,参数列表的数量以及每个列表中的参数数量(及其类型)必须与声明匹配
另一个例子。以下方法有两个参数列表:
println(foo()()()()()()()(1)(20)(300))
您可以按如下方式调用它:
def foo()()()()()()()(a: Int)(b: Int)(c: Int): Int = a + b + c
def bar(i: Int)(f: Int => Int) = f(i)
但并非如此
bar(42)(x => x * x)
或者类似的东西
完全类似地,如果您定义了一个具有零参数列表的方法
bar()(x => x * x)
bar()(42)(x => x * x)
bar(42)()
然后必须使用零参数列表调用它:
def baz = (x: Int) => x * x
由于它返回一个Int=>Int
函数,您当然可以将结果应用于Int
:
baz
这与(baz)(42)
相同,但不能执行以下操作:
baz(42)
因为baz
本身没有参数列表,()
不包含单个整数参数
请注意,以上所有内容实际上都是一种简化:在某些情况下,具有空参数列表的方法可以在不使用括号的情况下调用,即
def foo():Unit=…
可以作为foo
调用,而不使用()
。这是一个有点,我不能确切地说为什么它会在那里。我最好的猜测是:它与java互操作有关,在java互操作中,您确实希望省略零元getter上的括号。您,而不是相反。在你的文本中,一切似乎都是颠倒的,例如,“我们正在部分地将匿名函数应用于sum”没有任何意义-你将sum
应用于匿名函数,而不是反过来。要详细说明零元方法:约定是简单的getter没有参数列表,但是更复杂或有副作用的方法应该有括号。您可以在不使用括号的情况下调用其中一个函数的原因仅仅是为了java互操作,同时仍然保持这种约定。例如,最常见的情况可能是.toString
和.hashCode
。事实上,dotty计划对此进行更改,使java互操作和向后兼容性成为唯一允许的地方: