Scala cast to generic type (for generic numerical function)

心不动则不痛 提交于 2019-12-03 16:31:47
dk14

You can't cast Double to Integer anyway (because it's boxed). Numeric just allows you to have a set of mathematical operations (by import num._) on your T - nothing else (you don't need some mediate type for that). A2 works only because println expecting Any as a result of f(3), so T is automatically inferred to Any; println(f[Int](3)) will never work, f[Any](3) will always work.

If you want to implement generic function which operates Doubles (you may need that only if you have operations specific to Double) - you should better return Double. If you can't - you will have to construct the type manually by analizing T:

def f[A](x: A)(implicit num: Numeric[A]): A = {
   val result = new java.lang.Double(num.toDouble(x))
   (x match {
       case x: Double => result
       case x: Int => result.toInt
       case x: Float => result.toFloat
       case x: Long => result.toLong
   }).asInstanceOf[A]
}

The reason why you can't just do result.doubleValue.asInstanceOf[A] here is that A is already boxed. @specialized annotation doesn't work for asInstanceOf (type A is still boxed)

UPDATE: actually @specialized works:

def f[@specialized(Int, Double, Long, Float) A](x: A)(implicit num: Numeric[A]): A = {
   val result = new java.lang.Double(num.toDouble(x)) 

   result.doubleValue.asInstanceOf[A]
}

But it doesn't work in Scala REPL - so be careful!

P.S. Manifests are deprecated: use classTag/typeTag instead

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!