如何在Scala中为泛型类型指定Float和Double的类型绑定?

时间:2010-08-11 21:27:39

标签: generics scala type-bounds

我正在编写一些简单的Vector和Matrix类。它们看起来像这样:

// Vector with Floats
case class Vector3f(x: Float, y: Float, z: Float) {
  def +(v: Vector3f) = Vector3f(x + v.x, y + v.y, z + v.z)
}

// Vector with Doubles
case class Vector3d(x: Double, y: Double, z: Double) {
  def +(v: Vector3d) = Vector3d(x + v.x, y + v.y, z + v.z)
}

如果我继续使用其他方法和类,如Point3f / d,Vector4f / d,Matrix3f / d,Matrix4f / d ...这将是一项很多工作。 UFF ... 所以我认为泛型可以在这里提供帮助,并从我的代码库中删除冗余。我想到了这样的事情:

// first I define a generic Vector class
case class Vector3[@specialized(Float, Double) T](x: T, y: T, z: T) {
   def +(v: Vector3[T]) = new Vector3[T](x + v.x, y + v.y, z + v.z)
}

// than I use some type aliases to hide the generic nature
type Vector3f = Vector3[Float]
type Vector3d = Vector3[Double]

这个想法是scala编译器为Vector3 [Float]和Vector3 [Double]生成专门的类,就像C ++模板一样。不幸的是,我必须在类Vector3的类型参数[T]上放置一些类型绑定,以便在T上定义operator +。我的问题:如何编写Vector3 [Float],它具有与Vector3f相同的性能特征? 上下文:我想在碰撞检测代码中使用Vector3f / Vector3d类......所以性能对我来说很重要。

1 个答案:

答案 0 :(得分:4)

使用Fractional的上下文绑定:

case class Vector3[@specialized(Float, Double) T : Fractional](x: T, y: T, z: T)  { ...

然后在类的主体内,获取算术运算符的实例:

  val fractOps = implicitly[Fractional[T]]

最后将其成员导入该类的范围:

  import fractOps._

此后,您可以对类中使用的类型T的值编写普通的中缀操作。遗憾的是,您必须使用fractOps.div(a, b)代替a / b进行分割。