让我有一个名为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很新。我该如何解决这个问题?
答案 0 :(得分:11)
Numeric
type class instance有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
方法的实例,除非您导入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
如果上述情况不符合您的要求,请澄清您的问题。