scala tuple拆包

时间:2010-08-25 16:15:31

标签: scala parameters tuples

我知道这个问题以不同的方式出现过很多次。但我现在还不清楚。有没有办法实现以下目标。

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
}

5 个答案:

答案 0 :(得分:101)

这是一个两步程序。首先将foo转换为函数,然后在其上调用tupled以使其成为元组的函数。

(foo _).tupled(getParams)

答案 1 :(得分:52)

@ dave-griffith已经死了。

您也可以致电:

Function.tupled(foo _)

如果你想进入“比我要求的更多信息”领域,还有一些内置于部分应用函数(和Function)的方法用于currying。一些输入/输出示例:

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为此建立了内容:

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>

答案 2 :(得分:19)

Function.tupled(foo _)(getParams)或Dave建议的那个。

修改

回复您的评论:

  

如果foo恰好是   某类的构造函数?

在这种情况下,这个技巧将不起作用。

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

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)

我知道很多代码重复但是唉...我们还没有宏(还)! ;)

答案 3 :(得分:3)

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

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

答案 4 :(得分:1)

现在,您可以实现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)