Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法在scala中调用vararg方法_Scala_Reflection_Methods_Invoke_Variadic Functions - Fatal编程技术网

无法在scala中调用vararg方法

无法在scala中调用vararg方法,scala,reflection,methods,invoke,variadic-functions,Scala,Reflection,Methods,Invoke,Variadic Functions,我正在scala中创建一个组合分析器。解析树由我在计算解析表达式时需要访问的操作组成。其中一个操作函数将通过反射调用另一个对象上的方法,但如果该对象是vararg方法,则此操作将失败 这是演示问题的代码: 有人知道如何解决这个问题吗?这只是一个复制粘贴解决方案,但我相信你会明白: case class VarArgsFunction(Name: String, Args: Action*) extends Action { def visit: Double = { typeOf[

我正在scala中创建一个组合分析器。解析树由我在计算解析表达式时需要访问的操作组成。其中一个操作函数将通过反射调用另一个对象上的方法,但如果该对象是vararg方法,则此操作将失败

这是演示问题的代码:


有人知道如何解决这个问题吗?

这只是一个复制粘贴解决方案,但我相信你会明白:

case class VarArgsFunction(Name: String, Args: Action*) extends Action {
  def visit: Double = {
    typeOf[M].member(Name: TermName) match {
      case NoSymbol     => throw new Error(s"Unknown function '$Name'")
      case func: Symbol => {
        runtimeMirror(getClass.getClassLoader).reflect(new M).reflectMethod(func.asMethod)(
          (for { arg <- Args } yield arg.visit).toList).asInstanceOf[Double]
      }
    }
  }
}

object Parser {
  def main(args: Array[String]) {
    // Prints 2.718281828459045
    println(Function("e").visit)

    // Prints 7.0
    println(Function("add", Number(3), Number(4)).visit)

    // Prints 1.2246467991473532E-16
    println(Function("sin", Number(180)).visit)

    // Throws IllegalArgumentException: wrong number of arguments
    println(VarArgsFunction("max", Number(1), Number(2.5), Number(50), Number(-3)).visit)
  }
}

我知道您的解决方案适用于对vararg方法的调用,但是在解析和访问过程中,我无法知道所调用的方法是否为vararg方法。哎呀,有一点反射API遗漏了。func是一个MethodSymbol,具有isVarargs方法。
case class VarArgsFunction(Name: String, Args: Action*) extends Action {
  def visit: Double = {
    typeOf[M].member(Name: TermName) match {
      case NoSymbol     => throw new Error(s"Unknown function '$Name'")
      case func: Symbol => {
        runtimeMirror(getClass.getClassLoader).reflect(new M).reflectMethod(func.asMethod)(
          (for { arg <- Args } yield arg.visit).toList).asInstanceOf[Double]
      }
    }
  }
}

object Parser {
  def main(args: Array[String]) {
    // Prints 2.718281828459045
    println(Function("e").visit)

    // Prints 7.0
    println(Function("add", Number(3), Number(4)).visit)

    // Prints 1.2246467991473532E-16
    println(Function("sin", Number(180)).visit)

    // Throws IllegalArgumentException: wrong number of arguments
    println(VarArgsFunction("max", Number(1), Number(2.5), Number(50), Number(-3)).visit)
  }
}