Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.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中运行时检查参数类型(来自可变长度参数列表)_Scala_Variadic Functions_Runtime Type - Fatal编程技术网

在Scala中运行时检查参数类型(来自可变长度参数列表)

在Scala中运行时检查参数类型(来自可变长度参数列表),scala,variadic-functions,runtime-type,Scala,Variadic Functions,Runtime Type,我正在为一个系统设计接口,该系统可以接受应用于给定数据结构的规则 主系统被认为是一个接收命令的驱动程序,比如“将规则X应用于参数U、V、W,…”。我在编译时不知道所有可能的规则,所以我想在规则定义中嵌入参数类型信息,然后验证它 目前规则定义如下: trait Rule { val argTypes: Seq[Class[_]] def apply(stt: State, args: Seq[Any]) } args中的实际参数数量必须与argTypes中定义的类型数量匹配,并且方法ap

我正在为一个系统设计接口,该系统可以接受应用于给定数据结构的规则

主系统被认为是一个接收命令的驱动程序,比如“将规则X应用于参数U、V、W,…”。我在编译时不知道所有可能的规则,所以我想在规则定义中嵌入参数类型信息,然后验证它

目前规则定义如下:

trait Rule {
  val argTypes: Seq[Class[_]]
  def apply(stt: State, args: Seq[Any])
}
args
中的实际参数数量必须与
argTypes
中定义的类型数量匹配,并且方法
apply
应返回一个操作状态的值。(事实上,这是一个简化的解释,但这是总体思路)

我还实现了一个名为
checkTypes
的函数,以验证实际参数的类型是否与
argTypes
中定义的类型匹配

def checkTypes(args: Seq[Any]) {
  if (argTypes.size != args.size) {
    val msg = "Number of arguments (%d) does not match expected number (%d)."
    throw new IllegalArgumentException(msg.format(args.size, argTypes.size))
  }
  val err = "Incompatible argument type for [%s]. Expected: %s. Found: %s."
  for (i <- 0 until argTypes.size) {
    val formalClass = argTypes(i)
    val arg = args(i)
    val actualClass = arg.asInstanceOf[AnyRef].getClass
    if (!(formalClass isAssignableFrom actualClass)) {
      val errMsg = err.format(arg, formalClass.getName, actualClass.getName)
      throw new IllegalArgumentException(errMsg)
    }
  }
}

装箱类型(
java.lang.Integer
)与未装箱类型(
scala.Int
==java
Int
)不匹配。实际的实例是装箱的,但是您要针对的是原始类

下面是装箱基本体时发生的情况的示例:

scala> 5.getClass
res0: Class[Int] = int

scala> (5: Any)
res1: Any = 5

scala> res1.getClass
res2: Class[_] = class java.lang.Integer
请注意,如果您在
Any
上进行模式匹配并获得一个原语,它实际上会挑出装箱副本并为您解除装箱

scala> res1 match { case i: Int => println(i); case _ => }
5

既然你知道你必须被装箱,考虑到你写的代码,你可以只检查
Integer
而不是
Int
(也就是说,使用
classOf[Integer]
)。

@RexKerr实际上我不知道可以直接在字符串上调用
toInt
,但是,即使在做了您建议的更改之后,我仍然会收到相同的错误。谢谢您的帮助,但我仍然不确定什么是解决我的问题的最佳方法。将
argTypes
的声明更改为使用
classOf[Integer]
而不是
classOf[Int]
scala> res1 match { case i: Int => println(i); case _ => }
5