比较Scala

时间:2016-02-14 09:35:58

标签: scala generics

以下功能

def compare[T] (o1:T, o2:T):Boolean = {
   o1 > o2
}

将无法编译,因为value > is not a member of type parameter T

将参数定义为类型AnyVal也不起作用,编译器也会出现类似的错误。

但是,只能使用StringLong类型的值调用该函数,它们支持>

写这样一个函数的推荐灵魂是什么?

由于

4 个答案:

答案 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
}