我正在爲可以接受應用於給定數據結構的規則的系統設計接口。在運行時在Scala中檢查參數類型(來自可變長度參數列表)
主系統應該作爲一個驅動程序接收命令,如「將規則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)
}
}
}
的問題是,每當我試圖傳遞整數參數(從控制檯或文本文件中讀取)checkTypes
過程失敗,出現此消息:java.lang.IllegalArgumentException: Incompatible argument type for [1]. Expected: int. Found: java.lang.Integer.
我與Integer.parseInt(t).asInstanceOf[Int]
和規則轉換的整數參數期待兩種類型的參數Int
那麼,有沒有更有效的方法來檢查運行時的參數類型?
OR
如何轉換String
到Int
是真的嗎?
在此先感謝。
作爲最低工作示例,這是斯卡拉REPL會話發源於例外:scala.Int
scala> val argTypes: Seq[Class[_]] = Seq(classOf[Int], classOf[Int])
argTypes: Seq[Class[_]] = List(int, int)
scala> 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)
| }
| }
| }
checkTypes: (args: Seq[Any])Unit
scala> val args: Seq[Any] = Seq("1".toInt, "2".toInt)
args: Seq[Any] = List(1, 2)
scala> checkTypes(args)
java.lang.IllegalArgumentException: Incompatible argument type for [1]. Expected: int. Found: java.lang.Integer.
at $anonfun$checkTypes$1.apply$mcVI$sp(<console>:20)
at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:78)
at .checkTypes(<console>:14)
at .<init>(<console>:11)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:679)
@RexKerr其實我不知道可以直接在字符串上調用'toInt',但即使進行了更改後,仍然顯示我仍然收到同樣的錯誤。 – Jeff 2013-02-25 00:04:56