斯卡拉元组拆包

我知道这个问题已经以不同的方式出现过很多次了。 但是我还是不清楚。 有没有办法做到以下几点。

def foo(a:Int, b:Int) = {} foo(a,b) //right way to invoke foo foo(getParams) // is there a way to get this working without explicitly unpacking the tuple?? def getParams = { //Some calculations (a,b) //where a & b are Int } 

这是一个两步的过程。 首先把foo变成一个函数,然后调用tupled使其成为一个元组的函数。

 (foo _).tupled(getParams) 

@戴夫 – 格里菲斯已经死了。

您也可以致电:

 Function.tupled(foo _) 

如果你想徘徊于“比我所要求的领域更多的信息”的地方,也有部分应用function(和Function )中的方法,用于柯里化。 一些input/输出示例:

 scala> def foo(x: Int, y: Double) = x * y foo: (x: Int,y: Double)Double scala> foo _ res0: (Int, Double) => Double = <function2> scala> foo _ tupled res1: ((Int, Double)) => Double = <function1> scala> foo _ curried res2: (Int) => (Double) => Double = <function1> scala> Function.tupled(foo _) res3: ((Int, Double)) => Double = <function1> // Function.curried is deprecated scala> Function.curried(foo _) warning: there were deprecation warnings; re-run with -deprecation for details res6: (Int) => (Double) => Double = <function1> 

其中curried版本被多个参数列表调用:

 scala> val c = foo _ curried c: (Int) => (Double) => Double = <function1> scala> c(5) res13: (Double) => Double = <function1> scala> c(5)(10) res14: Double = 50.0 

最后,如果需要,你也可以放弃/取消。 Function已经build立了这个:

 scala> val f = foo _ tupled f: ((Int, Double)) => Double = <function1> scala> val c = foo _ curried c: (Int) => (Double) => Double = <function1> scala> Function.uncurried(c) res9: (Int, Double) => Double = <function2> scala> Function.untupled(f) res12: (Int, Double) => Double = <function2> 

Function.tupled(foo _)(getParams)或Davebuild议的。

编辑:

回应你的评论:

如果foo碰巧是某个类的构造函数呢?

在这种情况下,这个技巧是行不通的。

您可以在您的类的伴随对象中编写工厂方法,然后使用上述技术之一获取其apply方法的元组版本。

 scala> class Person(firstName: String, lastName: String) { | override def toString = firstName + " " + lastName | } defined class Person scala> object Person { | def apply(firstName: String, lastName: String) = new Person(firstName, lastName) | } defined module Person scala> (Person.apply _).tupled(("Rahul", "G")) res17: Person = Rahul G 

使用case class es,您可以免费获得一个apply方法的伴侣对象,因此这种方法可以更方便地与case class es一起使用。

 scala> case class Person(firstName: String, lastName: String) defined class Person scala> Person.tupled(("Rahul", "G")) res18: Person = Person(Rahul,G) 

我知道这是很多代码重复,但唉…我们没有macros(还)! ;)

我赞赏其他一些接近你所要求的答案,但是我发现当前项目更容易添加另一个将元组参数转换为分割参数的函数:

 def originalFunc(a: A, b: B): C = ... def wrapperFunc(ab: (A, B)): C = (originalFunc _).tupled(ab) 

现在,你可以实现foo,并使它像Tuple2类的参数。

 def foo(t: Tuple2[Int, Int]) = { println("Hello " + t._1 + t._2) "Makes no sense but ok!" } def getParams = { //Some calculations val a = 1; val b = 2; (a, b) //where a & b are Int } // So you can do this! foo(getParams) // With that said, you can also do this! foo(1, 3)