Scala Numeric init,常量为0

时间:2012-06-22 19:53:54

标签: scala numeric

让我有一个名为MathUtil的实用程序类。

它看起来像这样。

abstract class MathUtil(T:Numeric){
   def nextNumber(value:T)
   def result():T
}

让我以这种方式继承它

class SumUtil[T:Numeric] extends MathUtil[T]{
   private var sum:T = 0
   override def nextNumber(value:T){
     sum = sum + value
   }
   override def result():T = sum
}

我的陈述有问题

private var sum:T = 0

现在,我必须初始化为总和0.我猜任何数字都有办法表示0.我对scala很新。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:11)

Numeric type class instancezero方法可以执行您想要的操作:

class SumUtil[T: Numeric] extends MathUtil[T] {
   private var sum: T = implicitly[Numeric[T]].zero
   override def nextNumber(value: T) {
     sum = implicitly[Numeric[T]].plus(sum, value)
   }
   override def result(): T = sum
}

请注意,您还需要plus方法的实例,除非您导入Numeric.Implicits._,在这种情况下您可以使用+。在这种情况下,您也可以通过不使用上下文绑定语法来清理代码:

class SumUtil[T](implicit ev: Numeric[T]) extends MathUtil[T] {
   import Numeric.Implicits._
   private var sum: T = ev.zero
   override def nextNumber(value: T) {
     sum = sum + value
   }
   override def result(): T = sum
}

这完全等价:上下文绑定版本只是这个隐式参数的语法糖,但是如果你需要明确地使用那个参数(正如你在这里做的那样,对于它的zero),我发现它更清晰写下这个荒谬的版本。

答案 1 :(得分:0)

我认为需要对你要完成的目标做一点澄清。从Scala文档中,Numeric类型本身是通用的。我的感觉是你真正想要的是描述一个MathUtil抽象来处理任何Numeric [T]而不是Numeric [_]的子类,这是你的代码当前描述的。以下是基于该假设的正确实现。

//Define a MathUtil that works on any T
abstract class MathUtil[T] {
    def nextNumber(value: T)
    def result(): T
}

//Define a SumUtil that works on any T that has an available Numeric
//Will search implicit scope, but also allows you to provide an
//implementation if desired.
class SumUtil[T](implicit n: Numeric[T]) extends MathUtil[T] {
    //Use the Numeric to generate the zero correctly.
    private var sum: T = n.zero
    //Use the Numeric to correctly add the sum and value
    override def nextNumber(value: T) = sum = n.plus(sum, value)
    override def result(): T = sum
}

//Test that it works.
val a = new SumUtil[Int]
val b = List(1,2,3)

b map a.nextNumber //Quick and dirty test... returns a meaningless list
println(a.result)  //Does indeed print 6

如果上述情况不符合您的要求,请澄清您的问题。