2

我正在编写一些简单的 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 ......这将是很多工作。呃...所以我认为泛型可以在这里提供帮助并从我的代码库中删除冗余。我想到了这样的事情:

// 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 上定义运算符 +。我的问题:如何编写 Vector3[Float] 使其具有与 Vector3f 相同的性能特征?上下文:我想在碰撞检测代码中使用 Vector3f / Vector3d 类......所以性能对我来说很重要。

4

1 回答 1

5

使用 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除法。

于 2010-08-11T22:13:05.180 回答