Как передать аргумент кортежа лучшим способом?
Как передать аргумент кортежа лучшим способом?
Пример:
def foo(...): (Int, Int) = ...
def bar(a: Int, b: Int) = ...
Теперь я хотел бы передать вывод foo
в bar
. Это может быть достигнуто с помощью:
val fooResult = foo(...)
bar(fooResult._1, fooResult._2)
Этот подход выглядит немного уродливым, особенно когда мы имеем дело с n
-tuple с n > 2
. Также нам нужно сохранить результат foo в дополнительном значении, потому что иначе foo
должен выполняться более одного раза с помощью bar(foo._1, foo._2)
.
Есть ли лучший способ передать кортеж в качестве аргумента?
Ответы
Ответ 1
Для каждой функции существует специальный метод tupled
:
val bar2 = (bar _).tupled // or Function.tupled(bar _)
bar2
принимает кортеж (Int, Int)
(тот же, что и аргументы bar
). Теперь вы можете сказать:
bar2(foo())
Если ваши методы были фактически функциями (обратите внимание на ключевое слово val
), синтаксис намного приятнее:
val bar = (a: Int, b: Int) => //...
bar.tupled(foo())
См. также
Ответ 2
Использование tupled
, как упоминает @Tomasz, является хорошим подходом.
Вы также можете извлечь кортеж, возвращенный из foo
во время назначения:
val (x, y) = foo(5)
bar(x, y)
Это имеет преимущество более чистого кода (нет _1
и _2
) и позволяет назначать описательные имена для x
и y
, что делает ваш код более удобным для чтения.
Ответ 3
Стоит также знать о
foo(...) match { case (a,b) => bar(a,b) }
в качестве альтернативы, которая не требует, чтобы вы явно создавали временную fooResult
. Это хороший компромисс, когда важны скорость и отсутствие беспорядка. Вы можете создать функцию с помощью bar _
, а затем преобразовать ее, чтобы принять один аргумент кортежа с помощью .tupled
, но при каждом вызове пары создается два новых объекта функции; вы можете сохранить результат, но это может загромождать ваш код без необходимости.
Для повседневного использования (т.е. это не ограничивающая производительность часть вашего кода), вы можете просто
(bar _).tupled(foo(...))
в строке. Конечно, вы создаете два дополнительных объекта функции, но вы, скорее всего, просто создали кортеж, так что вам все равно, не так ли?