这两个Scala定义有什么区别

pri*_*ime 1 scala

我在Scala中具有以下2个定义,这给了我相同的结果。但这彼此有点不同。

def sum(f: Int => Int)(a: Int, b: Int): Int =
if (a > b) 0 else f(a) + sum(f)(a + 1, b)     //> sum: (f: Int => Int)(a: Int, b: Int)Int

sum(x => x*x)(1,2)   //> res3: Int = 5  
Run Code Online (Sandbox Code Playgroud)

第二个是

def sum(f: Int => Int,a: Int, b: Int): Int =
if (a > b) 0 else f(a) + sum(f,a + 1, b)      //> sum2: (f: Int => Int, a: Int, b: Int)Int

sum(x => x*x,1,2)                               //> res4: Int = 5
Run Code Online (Sandbox Code Playgroud)

我看到的唯一区别是sum(f: Int => Int,a: Int, b: Int)sum(f: Int => Int)(a: Int, b: Int)。在后一种情况下,功能参数和值参数是分开的。

这是什么行为。这是真的一样还是彼此不同?

Jas*_*man 5

关于您使用它们的方式,它们几乎相同。但是第一个版本通常具有一些额外的灵活性(和实用性)。

例如

val g = sum(x => x*x) _  //g has type (Int, Int) => Int
println(g(2, 3))         //prints 13
Run Code Online (Sandbox Code Playgroud)

这称为“咖喱”。您可以使用两个以上的参数列表来执行此操作,例如

def foo(b: Boolean)(i: Int)(s: String)(d: Double): Int = ...
val g = foo(true) _  //g has type Int => (String => (Double => Int))
val h = g(3) _       //h has type String => (Double => Int)
val r = h("asdf") _  //r has type Double => Int
Run Code Online (Sandbox Code Playgroud)

下划线有时可能会视上下文而定,例如

val r: Int => Double = foo(true)(3)("asdf")
Run Code Online (Sandbox Code Playgroud)

多个参数列表也用于隐式参数,以及在Scala编译器需要一些类型推断帮助时。当与按名字调用参数一起使用时,它们也可以方便地通过库创建伪造的语法或控制结构,例如

def repeat(n: Int)(body: => Unit) { 
  var i = n
  while (i > 0) { i -= 1; body }
}

var counter = 0
repeat(10) {                  //This method call (repeat) looks a bit like a part                   
  println(s"Hello: $counter") //of the language due to call-by-name argument, 
  counter += 1                //multiple parameter lists, use of curly braces, etc.
} 
Run Code Online (Sandbox Code Playgroud)

结果是

您好:1您好:2。。。你好9