理解curala

Rpa*_*ant 2 scala

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
Run Code Online (Sandbox Code Playgroud)

我觉得我不太了解好干.在第一个语句中,我们调用sumCubes没有参数,因此sum使用匿名函数作为参数调用并返回一个function2.

在第二次和第三次调用中真的发生了什么,为什么我们能够做到

sum(a => a * a * a)(1,10)
Run Code Online (Sandbox Code Playgroud)

但不是

sumCubes()(1,10)
Run Code Online (Sandbox Code Playgroud)

我的理解是sum(a => a * a * a)(1,10),我们部分应用于sum匿名函数,它返回一个Function2,它应用于第二对参数(1,10),因此我们得到3025,

但是sumCubes()(1,10),sumCubes如果首先调用不带参数,将sum使用匿名函数调用调用并返回的Function2将应用于(1,10)

为什么sumCubes(1,10)工作但不是sumCubes()(1,10),不应该sumCubessumCubes()意思相同,调用函数sumCubes.另外,如果一个简单的引用sumCubes正在调用它,我该如何传递它.我觉得我不了解Scala的基本内容.

And*_*kin 7

Scala的方法可以有多个参数列表.

例如,这是一个foo有十个参数列表的方法,其中前七个是空的:

def foo()()()()()()()(a: Int)(b: Int)(c: Int): Int = a + b + c
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式调用它:

println(foo()()()()()()()(1)(20)(300))
Run Code Online (Sandbox Code Playgroud)

它会打印出来321.

请注意,在调用方法时,参数列表的数量以及每个列表中的参数数量(以及它们的类型)必须与声明匹配.

另一个例子.以下方法有两个参数列表:

def bar(i: Int)(f: Int => Int) = f(i)
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式调用它:

bar(42)(x => x * x)
Run Code Online (Sandbox Code Playgroud)

但不是

bar()(x => x * x)
bar()(42)(x => x * x)
bar(42)()
Run Code Online (Sandbox Code Playgroud)

或类似的东西.

完全类似地,如果您已经定义了一个参数列表的方法

def baz = (x: Int) => x * x
Run Code Online (Sandbox Code Playgroud)

那么你也必须用参数列表调用它:

baz
Run Code Online (Sandbox Code Playgroud)

由于它返回一个Int => Int函数,你当然可以将结果应用于Int:

baz(42)
Run Code Online (Sandbox Code Playgroud)

这是相同的(baz)(42),但你不能做到以下几点:

baz()(42)
Run Code Online (Sandbox Code Playgroud)

因为baz它本身没有参数列表,并且()不包含单个整数参数.


请注意,以上所有内容实际上都是一种简化:在某些情况下,具有空参数列表的方法可以在没有括号的情况下def foo(): Unit = ...调用,即可以在没有括号的foo情况下调用().这是一个有点奇怪的功能,我不能确切地说它为什么存在.我最好的猜测是:它与java-interop有关,你真的想省略零-get getters的括号.

  • 详细说明零度方法:惯例是简单的getter没有参数列表,但是更复杂或有一些副作用的方法应该有括号.你可以在没有括号的情况下调用其中一个的原因仅仅是java-interop,同时仍然保持这个约定.例如,最常见的情况可能是`.toString`和`.hashCode`.实际上有点计划改变这个以使java互操作和向后兼容**允许这样的地方:https://dotty.epfl.ch/docs/reference/dropped/auto-apply.html (2认同)