是的,你可以,虽然语法可以说是非常笨拙,并且有一些限制,一开始可能看起来有点武断。诀窍是将方法转换为函数(称为“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
}
还有一个例子:
val foo = new Foo
还有一些你想使用Foo
's 方法的数据:
val names = ("John", "Doe")
val nums = (42, 3, 37)
你不能只写foo.f(names)
or foo.g(nums)
,因为类型不对齐——参数列表和元组在 Scala 中是不同的东西。但是您可以编写以下内容:
scala> (foo.f _).tupled(names)
res0: String = Doe, John
scala> (foo.g _).tupled(nums)
res1: Int = 153
在方法之后添加下划线将其转换为函数(在我看来,这是 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
不过,我不确定那会好得多。
最后,您不能(方便地)在 varargs 方法上使用这种方法——例如,您不能编写以下内容:
val coordsTupleToString = ("(%4.1f, %4.1f) to (%4.1f, %4.1f)".format _).tupled
甚至只是:
val coordsToString = "(%4.1f, %4.1f) to (%4.1f, %4.1f)".format _
这是在 Scala 中避免使用可变参数的另一个原因。