如何以最佳方式传递元组参数?

Joh*_*ood 35 arguments scala tuples

如何以最佳方式传递元组参数?

例:

def foo(...): (Int, Int) = ...

def bar(a: Int, b: Int) = ...
Run Code Online (Sandbox Code Playgroud)

现在我想将输出传递foobar.这可以通过以下方式实现:

val fooResult = foo(...)
bar(fooResult._1, fooResult._2)
Run Code Online (Sandbox Code Playgroud)

这种方法看起来有点难看,特别是当我们处理一个n-tuple时n > 2.此外,我们必须将foo的结果存储在一个额外的值中,因为否则foo必须使用多次执行bar(foo._1, foo._2).

有没有更好的方法来通过元组作为参数?

Tom*_*icz 52

tupled每种功能都有一种特殊的方法:

val bar2 = (bar _).tupled  // or Function.tupled(bar _)
Run Code Online (Sandbox Code Playgroud)

bar2取一个元组(Int, Int)(与bar参数相同).现在你可以说:

bar2(foo())
Run Code Online (Sandbox Code Playgroud)

如果你的方法实际上是函数(注意val关键字),语法会更加愉快:

val bar = (a: Int, b: Int) => //...
bar.tupled(foo())
Run Code Online (Sandbox Code Playgroud)

也可以看看

  • @JohnThreepwood:Scala中的方法转换为Java中的方法.Scala中的函数转换为对象.在Scala中,这大部分是透明的(搜索"*eta-expansion*"),但有时语法略有不同.[本文](http://jim-mcbeath.blogspot.no/2009/05/scala-functions-vs-methods.html)非常全面. (3认同)

dhg*_*dhg 9

使用tupled,如@Tomasz提到,是一个不错的办法.

您还可以提取foo在赋值期间返回的元组:

val (x, y) = foo(5)
bar(x, y)
Run Code Online (Sandbox Code Playgroud)

这有更清晰的代码的好处(不_1_2),并允许您为分配描述性名称xy,使代码更易于阅读.


Rex*_*err 9

值得了解的

foo(...) match { case (a,b) => bar(a,b) }
Run Code Online (Sandbox Code Playgroud)

作为替代方案,不需要您显式创建临时fooResult.当速度和缺乏混乱都很重要时,这是一个很好的妥协.您可以创建一个函数,bar _然后将其转换为使用单个元组参数.tupled,但每次调用该对时,这会创建两个新的函数对象; 您可以存储结果,但这可能会不必要地混乱您的代码.

对于日常使用(即这不是代码的性能限制部分),您可以

(bar _).tupled(foo(...))
Run Code Online (Sandbox Code Playgroud)

排队.当然,你创建了两个额外的函数对象,但你很可能只创建了元组,所以你不在乎那么多,对吧?