Можно ли использовать scala splat для чего-либо, что не является varargs?
например:
scala> def pipes(strings:String*) = strings.toList.mkString("|")
который я могу назвать нормально:
scala> pipes("foo", "bar")
res1: String = foo|bar
или с символом splat:
scala> val args = List("a","b","c")
scala> pipes(args:_*)
res2: String = a|b|c
Но могу ли я использовать splat для предоставления аргументов для чего угодно, кроме параметра varargs? например, я хотел бы сделать что-то вроде:
scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
scala> val args:Tuple2[Int, String] = (1, "two")
scala> pipeItAfterIncrementing(args:_*)
Это не работает, но есть ли способ добиться того же эффекта предоставления нескольких аргументов из одного объекта, будь то кортеж или что-то еще? Есть ли причина, по которой это невозможно реализовать для кортежей, учитывая, что как их длина, так и типы известны во время компиляции?
Ответы
Ответ 1
Вы можете использовать Function.tupled
для выполнения именно этого: превратите функцию, которая принимает n аргументов в функцию, которая принимает один аргумент аргумента arity n. Как и следовало ожидать, Function.untupled
выполняет обратное задание.
Специальный тип ascription : _*
применим только для повторного параметра (a.k.a. varargs).
scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
pipeItAfterIncrementing: (i: Int,s: String)java.lang.String
scala> def tupledPipeItAfterIncrementing = Function.tupled(pipeItAfterIncrementing _)
tupledPipeItAfterIncrementing: ((Int, String)) => java.lang.String
scala> val args:Tuple2[Int, String] = (1, "two")
args: (Int, String) = (1,two)
scala> tupledPipeItAfterIncrementing(args)
res0: java.lang.String = 2|two
Ответ 2
Ну вроде...
scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
scala> val args:Tuple2[Int, String] = (1, "two")
scala> (pipeItAfterIncrementing _).tupled(args)
предоставит вам желаемый 2|two
.