我想要一个封装整数和浮点数的类。
基本上我希望能够做到这样的事情
Const(5) + Const(6) = Const(11) Const(5) + Const(6.0) = Const(11.0)
包含编译器错误的代码。
case class Const[@specialized(Long,Double) T](value:T){
def +(that:Const[T]) : Const[T] = {
Const(this.value + that.value)
}
}
---- ---错误
:11:错误:类型不匹配; 发现:T 必需:字符串 Const(this.value + that.value)
(不确定为什么它会解析为字符串+运算符)
答案 0 :(得分:0)
这是一个工作版本(我认为当两个实例按不同类型参数化时,兼容用法需要类型参数):
case class Const[@specialized(Long, Double) T: scala.Numeric](value:T){
def +(that:Const[T]) : Const[T] = {
//Const(implicitly[Numeric[T]].mkNumericOps(this.value) + that.value)
import Numeric.Implicits._
Const(this.value + that.value)
}
}
用法:Const[Double](2) + Const(3.3)
答案 1 :(得分:0)
您希望能够以与Scala添加不同数字类型相同的方式添加Const
类的实例。但Scala不直接添加不同的数字类型,它使用隐式转换来首先使它们成为相同的类型。你也可以这样做。首先,您需要将Numeric
添加到您的班级,正如Gábor所说:
case class Const[@specialized(Long, Double) T: Numeric](value: T) {
import Numeric.Implicits._
def +(that: Const[T]) = Const(value + that.value)
}
然后,定义隐式转换:
implicit def constConvert[A, B: Numeric](a: Const[A])(implicit conv: A => B) =
Const[B](a.value)
这接受隐式转换,因此将内置隐式转换推广到您的类型。现在你可以写:
Const(5) + Const(6.0) // Const(11.0)
编译为:
constConvert(Const(5))(_.toDouble) + Const(6.0)
由于Scala为向上转换数字类型提供了合理的隐式转换,并且constConvert方法接受这种隐式转换,因此这通常适用于内置数字类型,以及定义合理转换和数字的任何新类型。
你应该知道,你不会真正从这里获得专业化的全部好处,因为标准库Numeric
并不是专门的(在撰写本文时),所以仍然会有自动装箱。您可能希望使用Numeric
的专用版本,例如Spire提供的版本。