SCALAの一般的なタイプでフロートにバインドされたタイプを指定し、2倍に指定するにはどうすればよいですか?
-
27-09-2019 - |
質問
私はいくつかの簡単なベクトルとマトリックスのクラスを書いています。彼らはこのように見えます:
// 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コンパイラがC ++テンプレートと同様のVector3 [Float]とVector3 [double]の特殊なクラスを生成するということです。残念ながら、演算子 +がTで定義されるように、クラスvector3のタイプパラメーター[t]に何らかのタイプをバインドする必要があります。私の質問:vector3 [float]をVector3fと同じパフォーマンス特性を持っていると書くにはどうすればよいですか?コンテキスト:衝突検出コードでVector3F / Vector3Dクラスを使用したいと思います。そのため、パフォーマンスは私にとって重要です。
解決
分数のコンテキストバウンドを使用します。
case class Vector3[@specialized(Float, Double) T : Fractional](x: T, y: T, z: T) { ...
次に、クラスの本文内で、算術演算子のインスタンスを取得します。
val fractOps = implicitly[Fractional[T]]
最後に、メンバーをクラスの範囲にインポートします。
import fractOps._
その後、クラス内で使用されるタイプTの値に関する通常のINFIX操作を記述できます。悲しいことに、あなたは使用する必要があります fractOps.div(a, b)
それ以外の a / b
部門用。
所属していません StackOverflow