在使用上下文绑定类型参数时,是否有使用较短语法的方法?现在我有一个类似的东西
case class Vector2D[a : Numeric](x: a, y: a) {
val numA = implicitly[Numeric[a]]
def length2 = numA.plus(numA.times(x, x), numA.times(y, y))
}
它使更复杂的公式变得不可读。
尝试此REPL会话:
scala> case class Vector2D[T : Numeric](x: T, y: T) {
val numeric = implicitly[Numeric[T]]
import numeric._
def length2 = (x*x)+(y*y)
}
defined class Vector2D
scala> Vector2D(3,4).length2
res0: Int = 25
这是因为Numeric包含一个名为mkNumericOps的隐式转换,您可以如上所示导入该转换。如果它没有开箱即用,你可以自己滚动它的方式是:
scala> implicit class NumericOps[T](val x: T) extends AnyVal { def +(y: T)(implicit n: Numeric[T]): T = n.plus(x, y)
| def *(y: T)(implicit n: Numeric[T]): T = n.times(x, y)
| }
defined class NumericOps
scala> case class Vector2D[a : Numeric](x: a, y: a) { def length2 = (x*x)+(y*y) }
defined class Vector2D
scala> Vector2D(3,4).length2
res0: Int = 25
如果您使NumericOps
不是一个值类(不要扩展AnyVal),那么隐式Numeric可以在构造函数中使用,而不是在每个方法中使用,这可能更好,或者并不重要。
无论如何,没有必要自己写,因为Numeric已经有了mkNumericOps
。
这些"操作"类被称为"丰富我的库"模式。
Numeric.Ops
在这里而被导入以自动创建它的隐式是Numeric上的mkNumericOps
。
仅
import Numeric.Implicits._
则对于可以找到隐式数值的每种类型,
(按照@Havoc p的建议,只导入一个NumericOps实例的NumericOpss转换,可以更好地控制哪些类型的操作可用,但大多数情况下,Numeric.Implicits
应该很好)
关于更普遍的问题,当使用上下文边界类型参数时,是否有一个较短的语法:一般来说,没有。这取决于typeclass提供一些糖以使其易于使用,就像Numeric在这里所做的那样。
例如,在伴随对象中或多或少有一个application方法,这使得获取实例比隐式更容易
object Ordering {
def apply[T](implicit ord: Ordering[T]): Ordering[T] = implicitly[Ordering[T]]
}
这样您就可以只使用例如Ordering[Int]
而不是implicitly[Ordering[Int]]
来获得隐式。