Scala 中的多个参数列表和每个列表的多个参数之间有什么区别? [英] What's the difference between multiple parameters lists and multiple parameters per list in Scala?

查看:19
本文介绍了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 + ydef 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
}

或者对于thunk:

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) = ???

最后,在对相关帖子的回答中还有另外三个应用程序为什么 Scala 既提供多个参数列表又提供每个列表多个参数?.我只是将它们复制到这里,但要归功于 Knut Arne Vedaa、Kevin Wright 和即席.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆