斯卡拉; 您可以将多个参数定义为一个

Far*_*mor 3 functional-programming scala

你能定义一组变量供以后使用吗?

这里有一些伪代码突出了我的意图:

def coordinates = x1, y1, x2, y2

log("Drawing from (%4.1f, %4.1f) to (%4.1f, %4.1f)".format(coordinates))
canvas.drawLine(coordinates, linePaint)
Run Code Online (Sandbox Code Playgroud)

这是一个包含重复代码的工作示例.

log("Drawing from (%4.1f, %4.1f) to (%4.1f, %4.1f)".format(x1, y1, x2, y2))
canvas.drawLine(x1, y1, x2, y2, linePaint)
Run Code Online (Sandbox Code Playgroud)

Tra*_*own 6

是的,你可以,虽然语法可以说是可怕的笨重,并且有一些限制,起初可能看起来有点武断.诀窍是将方法转换为函数(称为"eta扩展"),然后使用该函数的tupled方法来获取可以应用于元组的函数.

假设你有一个这样的类:

class Foo {
  def f(a: String, b: String) = "%s, %s".format(b, a)
  def g(x: Int, y: Int, z: Int) = x + y * z
}
Run Code Online (Sandbox Code Playgroud)

一个例子:

val foo = new Foo
Run Code Online (Sandbox Code Playgroud)

还有一些您想要使用Foo的方法:

val names = ("John", "Doe")
val nums = (42, 3, 37)
Run Code Online (Sandbox Code Playgroud)

你不能只是写foo.f(names)或者foo.g(nums),因为类型没有排列 - 参数列表和元组在Scala中是不同的东西.但是你可以写下面的内容:

scala> (foo.f _).tupled(names)
res0: String = Doe, John

scala> (foo.g _).tupled(nums)
res1: Int = 153
Run Code Online (Sandbox Code Playgroud)

在方法之后粘贴下划线将其转换为函数(这在我看来是Scala语法中最令人困惑的小问题),tupled并将其从具有两个(或三个)参数的函数转换为具有单个元组参数的函数.

您可以通过定义以下辅助函数来稍微清理代码,例如:

scala> val myF = (foo.f _).tupled
myF: ((String, String)) => String = <function1>

scala> val myG = (foo.g _).tupled
myG: ((Int, Int, Int)) => Int = <function1>

scala> myF(names)
res2: String = Doe, John

scala> myG(nums)
res3: Int = 153
Run Code Online (Sandbox Code Playgroud)

不过,我不确定那会好得多.

最后,您不能(方便地)在varargs方法上使用此方法 - 您不能编写以下内容:

val coordsTupleToString = ("(%4.1f, %4.1f) to (%4.1f, %4.1f)".format _).tupled
Run Code Online (Sandbox Code Playgroud)

甚至只是:

val coordsToString = "(%4.1f, %4.1f) to (%4.1f, %4.1f)".format _
Run Code Online (Sandbox Code Playgroud)

这是避免Scala中的varargs的另一个原因.

  • 您可以在可变参数就好了,只要他们高兴的`Any`类型使用:`的printf( "%d%d%d%S",(1,2,3, "鱼")productIterator.toSeq :_*)` (2认同)