将所有参数作为单个数组传递给函数

时间:2015-07-29 20:22:46

标签: scala

这是特定于Scala的问题。

假设您有多个输入的功能(您无法修改),例如:

def test(x1: Int, x2:Int, x3: Int, x4: Int, x5: Int) = {
  //Some logic
} 

并假设您在单个数组中拥有该函数的所有输入,例如:

val inputs = Array(1, 2, 3, 4, 5)

有没有办法用单个数组输入调用test而不显式插入单个数组元素(如test(inputs(0),inputs(1),inputs(2),inputs(3),inputs(4))中所述)?

对于我事先不知道输入数量和数组中元素数量(但知道它们匹配)的情况,这一点尤为重要。

3 个答案:

答案 0 :(得分:3)

不,那是不可能的。通过使用:_*语法,可以将数组用于期望varargs的函数。此外,你的问题是矛盾的:

  

我不知道输入数量和数量的情况   提前在数组中的元素(但知道它们匹配)

你怎么能不知道输入或元素的数量,但知道它们匹配?

答案 1 :(得分:1)

您可以使用该功能,然后使用其中一个解决方案here

例如,使用this technique

class Acc[T](f: Function1[T, _]) {
  private[this] var ff: Any = f
  def apply(t: T): this.type = {
    ff = ff.asInstanceOf[Function1[T,_]](t)
    this
  }
  def get = ff match { 
    case _: Function1[_,_] => sys.error("not enough arguments")
    case res => res.asInstanceOf[T]
  }
}

def test(x1: Int, x2:Int, x3: Int, x4: Int, x5: Int) = {
  //Some logic
} 

val inputs = Array(1, 2, 3, 4, 5)

inputs.foldLeft(new Acc((test _).curried))((acc, i) => acc(i)).get

不是非常安全,但应该有效

答案 2 :(得分:0)

您可以使用Java反射(或Scala反射,但Java的反射就足够了)。以下是一个快速而肮脏的解决方案,假设您有一个类Test,其中只包含一个test方法:

val m = classOf[Test].
  getMethods.find(_.getName == "test").
  getOrElse(throw new Exception("No method called test"))

// inputs must be Array[Object], not Array[Int] as in your example
m.invoke(instanceOfTest, inputs)

然而,这不是一个好主意。