2014-11-08 43 views
1

当使用上下文绑定类型参数时,有没有办法使用更短的语法?目前我有这样的东西上下文边界的语法较短?

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)) 
} 

它使更复杂的公式不可读。

回答

2

试试这个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 

这是因为数字包含一个名为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),则可以在隐式数值去构造函数而不是每个方法,这可能会更好,或者不重要。

反正有没有必要写你自己的,因为数字已经mkNumericOps

这些“ops”类被称为“丰富我的图书馆”模式。

Numeric.Opshere 和进口隐式存在自动创建它是mkNumericOps上的数字,here

+0

你不需要'val numeric =隐式[Numeric [T]]'行,你永远不会使用它。 – lmm 2014-11-08 23:11:45

+0

它用在下一行? 'import numeric._' – 2014-11-09 02:54:21

2

只是

import Numeric.Implicits._ 

然后每一种类型,对于其中隐含的数字,可以发现

(由@Havoc数p作为建议进口只是一个数字实例的NumericOps转换为您提供了更精细的控制,到哪些类型的操作可用,但大多数时候,Numeric.Implicits应该没问题)

关于更一般的问题是使用上下文边界类型参数时,语法较短:通常,没有吨。正如Numeric在这里所做的那样,由类型类提供一些糖使其易于使用。

例如,它或多或少习惯在这使得越来越实例一点比隐含

object Ordering { 
    def apply[T](implicit ord: Ordering[T]): Ordering[T] = implicitly[Ordering[T]] 
} 

这样更容易,你可以得到的隐性只是如同伴对象中的应用方法Ordering[Int],而不是implicitly[Ordering[Int]]