使用Scala的2.8,你可寫:
case class Vector3[T: Numeric](val x: T, val y: T, val z: T) {
override def toString = "(%s, %s, %s)" format (x, y, z)
def add(that: Vector3[T]) = new Vector3(
plus(x, that.x),
plus(y, that.y),
plus(z, that.z)
)
private def plus(x: T, y: T) = implicitly[Numeric[T]] plus (x, y)
}
讓我解釋一下。首先,T: Numeric
是一個上下文綁定,它隱式地爲您的類提供了一個Numeric[T]
實例。
的Numeric[T]
性狀提供數字類型的操作,
trait Numeric[T] extends Ordering[T] {
def plus(x: T, y: T): T
def minus(x: T, y: T): T
def times(x: T, y: T): T
def negate(x: T): T
// other operations omitted
}
表達implicitly[Numeric[T]]
檢索,使得可以執行操作,諸如plus
您的具體參數的x,y和z,如在示出的該隱式上下文上面的私有方法。
現在,您可以構建和add
不同的Vector3
實例如用Int
的和Double
的:
scala> Vector3(1,2,3) add Vector3(4,5,6)
res1: Vector3[Int] = (5, 7, 9)
scala> Vector3(1.1, 2.2, 3.3) add Vector3(4.4, 5.5, 6.6)
res2: Vector3[Double] = (5.5, 7.7, 9.899999999999999)
側面說明:這是可以使用隱式轉換爲數值轉換爲Numeric[T].Ops
情況下,使得下面可以代替書面:
def add(that: Vector3[T]) = new Vector3(x + that.x, y + that.y, z + that.z)
我特意選擇不使用這些隱式轉換,因爲他們(可能)招致一些績效通過創建臨時包裝對象來懲罰。實際的性能影響取決於JVM(例如,爲了避免堆上的實際對象分配,其支持逃逸分析的程度)。使用上下文綁定和implicitly
避免了這種潛在的開銷...以一些冗長的代價。
在2.8這是'OPS',或者我被告知。我不知道2.7中該做什麼,但我是斯卡拉新手。 – erisco 2010-05-14 19:38:50