Scala有一个号码,你可以为类型类使用,如性状Ordered
,并Numeric
在包装中scala.math
.
例如,我可以使用Ordered
如下方法编写泛型方法:
def f[T <% Ordered[T]](a: T, b: T) = if (a < b) a else b
Run Code Online (Sandbox Code Playgroud)
我想做类似的事情Numeric
,但这不起作用:
def g[T <% Numeric[T]](a: T, b: T) = a * b
Run Code Online (Sandbox Code Playgroud)
为什么Ordered
和之间存在明显的差异Numeric
?
我知道还有其他方法可以做到这一点,以下方法将起作用(使用上下文绑定):
def g[T : Numeric](a: T, b: T) = implicitly[Numeric[T]].times(a, b)
Run Code Online (Sandbox Code Playgroud)
但这看起来比仅仅能够*
乘以两个数字更复杂.为什么Numeric
特征不包括类似的方法*
,而Ordered
包括类似的方法<
?
我知道Ordering
你也可以用同样的方式使用Numeric
,另见这个答案:
def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)
Run Code Online (Sandbox Code Playgroud)
Mil*_*bin 12
如果从隐式数值[T]导入它们,则符号运算符可用
def g[T : Numeric](a: T, b: T) = {
val num = implicitly[Numeric[T]]
import num._
a * b
}
Run Code Online (Sandbox Code Playgroud)
如果你想只使用一个运算符,这显然有点笨拙,但在非平凡的情况下,导入的开销并不是那么好.
如果没有明确的导入,为什么运营商不可用?默认情况下,默认情况下使隐含可见的常见考虑因素在这里适用,可能更多因为这些运算符被广泛使用.
Ordered
只是一些简单的拉皮条方法返回Int
或者Boolean
,所以不需要类型欺骗.
Numeric
另一方面,具有根据所使用的确切子类返回不同类型的方法.因此,虽然Ordered
只是一个标记特征,但它Numeric
是一个功能齐全的类型.
要使操作员返回,可以在lhs操作数上使用mkNumericOps
(定义Numeric
).
UPDATE
Miles非常正确,mkNumericOps
是隐含的,所以只需导入Numeric实例就能让你恢复所有的魔力......
你可以通过这样做来减少Miles的解决方案,只使用1个额外的行:
从添加的隐式转换A : Numeric
到Numeric[A]#Ops
object Ops {
implicit def numeric[A : Numeric](a: A) = implicitly[Numeric[A]].mkNumericOps(a)
}
Run Code Online (Sandbox Code Playgroud)
然后将其纳入您的方法的范围
def g[T : Numeric](a: T, b: T) = {
import Ops.numeric
a * b
}
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅Scala ticket 3538.
归档时间: |
|
查看次数: |
293 次 |
最近记录: |