以下功能
def compare[T] (o1:T, o2:T):Boolean = {
o1 > o2
}
将无法编译,因为value > is not a member of type parameter T
将参数定义为类型AnyVal
也不起作用,编译器也会出现类似的错误。
但是,只能使用String
和Long
类型的值调用该函数,它们支持>
。
写这样一个函数的推荐灵魂是什么?
由于
答案 0 :(得分:5)
您可以使用def compare[T](o1: T, o2: T)(implicit ord: Ordering[T]) = ord.gt(o1, o2)
类型类,如下所示:
Localhost
答案 1 :(得分:3)
如果您想使用>
运算符,可以使用查看绑定和Ordered[T]
def compare[T <% Ordered[T]] (o1:T, o2:T):Boolean = {
o1 > o2
}
scala文档中有很好的例子。
http://docs.scala-lang.org/tutorials/FAQ/context-and-view-bounds.html
或者您可以使用隐式参数来执行此操作,因为视图边界现在已弃用:
def compare[T](o1: T, o2: T)(implicit ev: T => Ordered[T]): Boolean = {
o1 < o2
}
答案 2 :(得分:2)
如果你想避免明确提到一个隐式参数,但也避免使用现在已弃用的视图边界,你可以通过定义类型别名来使用这样的上下文边界:
type OrderedView[T] = T => Ordered[T]
def compare[T: OrderedView](o1: T, o2: T) = {
o1 > o2
}
不幸的是,这种模式似乎没有很好地记录 - 当我试图找出如何在不使用上下文边界的情况下实现“丰富我的库”模式时,我在a post in the scala-internals mailing list找到了它。
答案 3 :(得分:0)
不推荐使用视图边界,不应使用它们,但可以使用上下文边界。这将为您提供对排序实例的隐式访问,您可以使用compare方法:
def compare[T: Ordering] (o1:T, o2:T):Boolean = {
val ord = implicitly[Ordering[T]]
ord.compare(o1, o2) > 0
}
现在,如果您必须使用运算符直接执行此操作,那么当然要好得多。订购直接提供隐式转换,您只需在本地导入:
def compare[T: Ordering] (o1:T, o2:T):Boolean = {
val ord = implicitly[Ordering[T]]
import ord.mkOrderingOps
o1 > o2
}