我正在编写一些简单的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类......所以性能对我来说很重要。
答案 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
进行分割。