从Azavea Numeric获取隐式scala数字
我使用Azavea Numeric Sc??ala库进行通用数学运算.但是,我不能将它们与
Scala Collections API一起使用,因为它们需要一个scala Numeric,看起来好像两个Numerics是互斥的.有什么方法可以避免重新实现对Azavea Numeric的Scala Collections的所有数学运算,除了要求所有类型都有Numerics的上下文界限?
import Predef.{any2stringadd => _,_} class Numeric { def addOne[T: com.azavea.math.Numeric](x: T) { import com.azavea.math.EasyImplicits._ val y = x + 1 // Compiles val seq = Seq(x) val z = seq.sum // Could not find implicit value for parameter num: Numeric[T] } } Azavea数字定义为 trait Numeric[@scala.specialized A] extends java.lang.Object with com.azavea.math.ConvertableFrom[A] with com.azavea.math.ConvertableTo[A] with scala.ScalaObject { def abs(a:A):A ...remaining methods redacted... } object Numeric { implicit object IntIsNumeric extends IntIsNumeric implicit object LongIsNumeric extends LongIsNumeric implicit object FloatIsNumeric extends FloatIsNumeric implicit object DoubleIsNumeric extends DoubleIsNumeric implicit object BigIntIsNumeric extends BigIntIsNumeric implicit object BigDecimalIsNumeric extends BigDecimalIsNumeric def numeric[@specialized(Int,Long,Float,Double) A:Numeric]:Numeric[A] = implicitly[Numeric[A]] } 解决方法
最通用的解决方案是编写一个包装com.azavea.math.Numeric的类,并根据它实现scala.math.Numeric:
class AzaveaNumericWrapper[T]( implicit val n: com.azavea.math.Numeric[T] ) extends scala.math.Numeric { def compare (x: T,y: T): Int = n.compare(x,y) def minus (x: T,y: T): T = n.minus(x,y) // and so on } 然后实现隐式转换: // NOTE: in scala 2.10,we could directly declare AzaveaNumericWrapper as an implicit class implicit def toAzaveaNumericWrapper[T]( implicit n: com.azavea.math.Numeric[T] ) = new AzaveaNumericWrapper( n ) n本身是隐式的这一事实是关键:它允许自动使用类型为com.azavea.math.Numeric的隐式值,其中na隐含值为 现在,上述解决方案存在一个缺点:每次调用都会得到一个转换(因此就是一个实例)(对于一个上下文类型为scala.math.Numeric的方法,你只有一个com实例. azavea.math.Numeric在范围内). implicit object MyTypeIsNumeric extends AzaveaNumericWrapper[MyType] implicit object MyOtherTypeIsNumeric extends AzaveaNumericWrapper[MyOtherType] //... 另外,请记住,azavea的Numeric类的明显主要目的是大大提高执行速度(主要是由于类型参数专门化). 你可能已经注意到我在我的例子中避免为Int,Long等类型定义AzaveaNumericWrapper的实例.这是因为对于这些类型,已经存在(在标准库中)scala.math.Numeric的隐式值.您可能想要隐藏它们(通过导入scala.math.Numeric.{ShortIsIntegral => _}之类的东西),以确保使用您自己的(azavea支持的)版本,但没有意义.我能想到的唯一原因是让它运行得更快,但如上所述,它不会. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |