给出以下n维数据点:
class Point private (private val data: Array[Double]) {
private def op(other: Point)(f: (Double, Double) => Double): Point = {
for (i <- data.indices)
data(i) = f(data(i), other.data(i))
this
}
private def op(scalar: Double)(f: (Double, Double) => Double): Point = {
for (i <- data.indices)
data(i) = f(data(i), scalar)
this
}
// Point scalar ops
def +(scalar: Double): Point = op(scalar)(_ + _)
def -(scalar: Double): Point = op(scalar)(_ - _)
def *(scalar: Double): Point = op(scalar)(_ * _)
def /(scalar: Double): Point = op(scalar)(_ / _)
// Point Point ops
def +(other: Point): Point = op(other)(_ + _)
def -(other: Point): Point = op(other)(_ - _)
def *(other: Point): Point = op(other)(_ * _)
def /(other: Point): Point = op(other)(_ / _)
override def toString: String = {
"Point(" + data.map(_.toString).mkString(", ") + ")"
}
}
object Point {
def apply(data: Double*): Point = new Point(Array(data:_*))
}
我可以执行以下操作:
val p1 = Point(1,2,3)
println(p1 + 3) // Point(4.0, 5.0, 6.0)
但是,我也希望有一种“双向”行为:
val p1 = Point(1,2,3)
println(3 + p1)
有什么方法可以在Scala中完成此操作吗?
答案 0 :(得分:6)
是的,可以。使用implicit class为标量值创建丰富的包装。
implicit class ScalarOps (val scalar: Double) extends AnyVal {
def + (point: Point): Point = point + scalar
// Other methods...
}
val p = Point(1, 2, 3)
1 + p // res0: Point = Point(2, 3, 4)
请注意,我将隐式类与value class组合在一起,因此在大多数情况下,您的包装器并未真正实例化。