7

让我有一个名为 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 很陌生。我该如何解决这个问题?

4

2 回答 2

12

Numeric类型类实例有一个zero方法可以满足您的需求:

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方法的实例,除非您 import 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),我发现编写脱糖版本更简洁。

于 2012-06-22T20:12:02.077 回答
0

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

//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

如果上述内容不能满足您的要求,请澄清您的问题。

于 2012-06-22T21:09:00.423 回答