[英]Scala Numeric init with constant 0
让我有一个名为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很新。 我该如何解决这个问题?
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
}
请注意,除非导入Numeric.Implicits._
,否则还需要plus
方法的实例,在这种情况下,您可以使用+
。 在这种情况下,您也可以通过不使用上下文绑定语法来清理代码:
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
),我发现编写desugared版本更清晰。
我认为需要对你要完成的目标做一点澄清。 从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
如果以上不符合您的要求,请澄清您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.