【发布时间】:2014-11-30 11:36:11
【问题描述】:
我正在尝试实现一个包含数学 Java 函数的通用函数。为简单起见,我们可以假设 Java 函数 (Java 7) 采用一个参数并返回一个结果,两者都是 java.lang.Double 类型。当然,包装函数应该接受一个参数和一个结果,两者都是通用但数字类型 A。问题是我无法在包装函数中将结果转换回类型 A。哪里/什么问题?
注意:(我是 Scala 的新手,使用以下参考来解决问题。)
- 我正在使用隐式类型特征 Numeric 来强制模板类型为数字。 How do I implement a generic mathematical function in Scala
- 我发现了“import scala.collection.JavaConversions._”,但我并不完全理解,但在我看来,它是为了转换 Java 集合而不能解决我的问题,是吗? Iterating over Java collections in Scala
- 如此处所述,我尝试使用 Manifest 强制执行正确的强制转换(变体 B),但最终导致异常 java.lang.ClassCastException。 Scala asInstanceOf with parameterized types
变体 A
package test
object mytest {
def f[A](x: A)(implicit num: Numeric[A]): A = {
val result = new java.lang.Double(num.toDouble(x))
result.asInstanceOf[A]
}
def main(args: Array[String]) {
// 'Some code'
}
}
'一些代码'A1
result val result = f(3)
输出:
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:105)
at test.mytest$.main(test.scala:10)
at test.mytest.main(test.scala)
'一些代码'A2
println(f(3))
输出:
3.0
'一些代码'A3
println(f(3).getClass)
输出:
int
变体 B
package test
object mytest {
def f[A : Manifest](x: A)(implicit num: Numeric[A]): A = {
val result = new java.lang.Double(num.toDouble(x))
manifest[A].erasure.cast(result).asInstanceOf[A]
}
def main(args: Array[String]) {
val result = f(3)
}
}
输出:
(这对于变体 A1、A2 和 A3 的等价物也是如此,因为现在在函数 f 的第 6 行中抛出了异常。)
Exception in thread "main" java.lang.ClassCastException: Cannot cast java.lang.Double to int
at java.lang.Class.cast(Class.java:3176)
at test.mytest$.f(test.scala:6)
at test.mytest$.main(test.scala:10)
at test.mytest.main(test.scala)
【问题讨论】:
标签: scala generics casting scala-java-interop