【问题标题】:passing all arguments to a function as a single array将所有参数作为单个数组传递给函数
【发布时间】:2015-07-30 06:00:24
【问题描述】:

这是一个 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)))?

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

【问题讨论】:

    标签: scala


    【解决方案1】:

    不,那是不可能的。通过使用:_* 语法,可以将数组用于需要可变参数的函数。另外,你的问题是矛盾的:

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

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

    【讨论】:

    • 我正在使用由其他人编写的许多函数,它们对应于 SQL 数据库中的某些表(每个函数的参数数与相应的列数相同)表)。我通过 JDBC 访问表,然后想运行这些函数来处理我的查询结果。是否至少可以生成inputsinputs(0),inputs(1),... 的就地扩展?例如。类似于test(for (i <- inputs) i)
    • @verse 你有没有考虑过不这样做?老实说,这听起来像是我听过的最不合理的方法。弄清楚如何将数组作为参数传递给该函数是您最不担心的事情。你有没有问过那个人为什么他们对你这么不尊重?
    【解决方案2】:

    您可以对函数进行 curry,然后使用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
    

    不是很安全,但应该可以工作

    【讨论】:

    【解决方案3】:

    您可以使用 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)
    

    然而,这很少是一个好主意。

    【讨论】:

      猜你喜欢
      • 2014-12-08
      • 1970-01-01
      • 2013-11-03
      • 2012-12-07
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      • 1970-01-01
      相关资源
      最近更新 更多