无法在 scala 中调用 vararg 方法



我正在scala中创建一个组合器解析器。解析树包含我在计算解析表达式时需要访问的操作。其中一个操作(函数)将通过反射在另一个对象上调用一个方法,但是当它是vararg方法时,这将失败。

这是演示该问题的代码:

import scala.reflect.runtime.universe._
class M {
  def e: Double = { Math.E }
  def add(x: Double, y: Double): Double = { x + y }
  def sin(x: Double): Double = { Math.sin(x * Math.PI / 180) }
  def max(args: Double*): Double = { args.max }
}
sealed trait Action { def visit: Double }
case class Number(value: Double) extends Action { def visit: Double = value }
case class Function(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(Function("max", Number(1), Number(2.5), Number(50), Number(-3)).visit)
  }
}

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

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

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)
  }
}

相关内容

  • 没有找到相关文章

最新更新