Scala中的多个参数列表和每个列表的多个参数之间有什么区别? [英] What's the difference between multiple parameters lists and multiple parameters per list in Scala?
问题描述
在Scala中,人们可以像这样编写(咖喱?)函数
In Scala one can write (curried?) functions like this
def curriedFunc(arg1: Int) (arg2: String) = { ... }
上面的具有两个参数列表的curriedFunc
函数定义与一个参数列表中具有多个参数的函数之间的区别是什么?
What is the difference between the above curriedFunc
function definition with two parameters lists and functions with multiple parameters in a single parameter list:
def curriedFunc(arg1: Int, arg2: String) = { ... }
从数学的角度来看,这是(curriedFunc(x))(y)
和curriedFunc(x,y)
,但是我可以写def sum(x) (y) = x + y
,而它也是def sum2(x, y) = x + y
From a mathematical point of view this is (curriedFunc(x))(y)
and curriedFunc(x,y)
but I can write def sum(x) (y) = x + y
and the same will be def sum2(x, y) = x + y
我只知道一个区别-这是部分应用的功能.但是这两种方式对我来说都是等效的.
I know only one difference - this is partially applied functions. But both ways are equivalent for me.
还有其他区别吗?
推荐答案
严格来说,这不是一个咖喱函数,而是具有多个参数列表的方法,尽管它看起来像一个函数.
Strictly speaking, this is not a curried function, but a method with multiple argument lists, although admittedly it looks like a function.
正如您所说,多个参数列表允许使用该方法代替部分应用的函数. (对不起,我使用的一般愚蠢的示例)
As you said, the multiple arguments lists allow the method to be used in the place of a partially applied function. (Sorry for the generally silly examples I use)
object NonCurr {
def tabulate[A](n: Int, fun: Int => A) = IndexedSeq.tabulate(n)(fun)
}
NonCurr.tabulate[Double](10, _) // not possible
val x = IndexedSeq.tabulate[Double](10) _ // possible. x is Function1 now
x(math.exp(_)) // complete the application
另一个好处是,您可以使用花括号代替括号,如果第二个参数列表由单个函数或thunk组成,则括号看起来不错.例如
Another benefit is that you can use curly braces instead of parenthesis which looks nice if the second argument list consists of a single function, or thunk. E.g.
NonCurr.tabulate(10, { i => val j = util.Random.nextInt(i + 1); i - i % 2 })
与
IndexedSeq.tabulate(10) { i =>
val j = util.Random.nextInt(i + 1)
i - i % 2
}
或者是笨蛋:
IndexedSeq.fill(10) {
println("debug: operating the random number generator")
util.Random.nextInt(99)
}
另一个优点是,您可以引用先前的参数列表中的参数来定义默认参数值(尽管您也可以说无法在单个列表中执行此操作是一个缺点:)
Another advantage is, you can refer to arguments of a previous argument list for defining default argument values (although you could also say it's a disadvantage that you cannot do that in single list :)
// again I'm not very creative with the example, so forgive me
def doSomething(f: java.io.File)(modDate: Long = f.lastModified) = ???
Finally, there are three other application in an answer to related post Why does Scala provide both multiple parameters lists and multiple parameters per list? . I will just copy them here, but the credit goes to Knut Arne Vedaa, Kevin Wright, and extempore.
首先:您可以有多个var args:
First: you can have multiple var args:
def foo(as: Int*)(bs: Int*)(cs: Int*) = as.sum * bs.sum * cs.sum
...在单个参数列表中是不可能的.
...which would not be possible in a single argument list.
第二,它有助于类型推断:
Second, it aids the type inference:
def foo[T](a: T, b: T)(op: (T,T) => T) = op(a, b)
foo(1, 2){_ + _} // compiler can infer the type of the op function
def foo2[T](a: T, b: T, op: (T,T) => T) = op(a, b)
foo2(1, 2, _ + _) // compiler too stupid, unfortunately
最后,这是拥有隐式和非隐式参数的唯一方法,因为implicit
是整个参数列表的修饰符:
And last, this is the only way you can have implicit and non implicit args, as implicit
is a modifier for a whole argument list:
def gaga [A](x: A)(implicit mf: Manifest[A]) = ??? // ok
def gaga2[A](x: A, implicit mf: Manifest[A]) = ??? // not possible
这篇关于Scala中的多个参数列表和每个列表的多个参数之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!