1

我想要一个封装整数和浮点数的类。

基本上我希望能够做这样的事情

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 必需:字符串常量(this.value + that.value)

(不知道为什么它解析为字符串 + 运算符)

4

2 回答 2

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)

于 2014-12-06T11:21:27.470 回答
0

您希望能够Const像 Scala 可以添加不同的数字类型一样添加类的实例。但是 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 方法接受这种隐式转换,这通常适用于内置数字类型,以及任何定义合理转换和 Numerics 的新类型。

然而!

您应该知道,在这里您不会真正获得专业化的全部好处,因为标准库Numeric不是专门化的(在撰写本文时),所以仍然会有自动装箱。相反,您可能想要使用SpireNumeric提供的专用版本。

于 2017-11-02T06:14:58.997 回答