当我第一次听说价值课时,我想 - 最后!现在我可以定义自己的数字类型sans对象分配!但结果却比我想象的更难。
我想定义我自己的Decimal类型,Dec64
(http://dec64.com/)或长支持小数,以进行快速货币计算。但是,AnyVal
无法扩展Numeric
,因为Numeric
不是普遍特征。我尝试跟进Double
的Scala代码,但它非常复杂,有AnyValCompanion
,FractionalProxy
和许多private[scala]
标记代码,非常有用的评论,如< em>不应在用户代码中扩展。
那么,我如何正确定义自己的数值类型,可以与其他Scala数字一起很好地发挥作用呢?
答案 0 :(得分:2)
Numeric
是一个类型类,所以你的类不会扩展它。相反,您将为您的类型创建类型类的实例。在下面的示例中,为简单起见,我使用Int
。
final class MyNum(val i: Int) extends AnyVal
object MyNum {
implicit val numeric: Numeric[MyNum] = new Numeric[MyNum] {
override def plus(x: MyNum, y: MyNum): MyNum = new MyNum(x.i + y.i)
override def minus(x: MyNum, y: MyNum): MyNum = new MyNum(x.i - y.i)
override def times(x: MyNum, y: MyNum): MyNum = new MyNum(x.i * y.i)
override def negate(x: MyNum): MyNum = new MyNum(-x.i)
override def fromInt(x: Int): MyNum = new MyNum(x)
override def toInt(x: MyNum): Int = x.i
override def toLong(x: MyNum): Long = x.i.toLong
override def toFloat(x: MyNum): Float = x.i.toFloat
override def toDouble(x: MyNum): Double = x.i.toDouble
override def compare(x: MyNum, y: MyNum): Int = x.i.compare(y.i)
}
}
如果您不熟悉类型类,我建议使用Learn You A Haskell For Great Good,尤其是type classes部分。无论如何,这只是一本很好的书,我强烈建议您阅读整篇文章,以充分了解这些想法的来源。