はい、できますが、構文は間違いなく恐ろしく不格好です。また、最初は少し恣意的に思えるかもしれないいくつかの制限があります。秘訣は、メソッドを関数に変換し (「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
:
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
2 つ (または 3 つ) の引数を持つ関数から単一のタプル引数を持つ関数に変換されます。
たとえば、次のヘルパー関数を定義することで、コードを少しきれいにすることができます。
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 で可変引数を避けるもう 1 つの理由です。