我在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)。在后一种情况下,功能参数和值参数是分开的。
这是什么行为。这是真的一样还是彼此不同?
关于您使用它们的方式,它们几乎相同。但是第一个版本通常具有一些额外的灵活性(和实用性)。
例如
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
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |