首先,我认为您的堆栈溢出的原因是使用了
[A <: Comparable[_]]
。 在实践中,
存在类型意味着您实际上无法将
A
与任何东西进行比较。 这意味着编译器在
self.compareTo
调用中“选择”隐式转换以重新调用(因此递归)。 如果您使用编译器开关
-XprintTypes,您会看到这一点。
那么怎么办呢?
考虑
Ordering
和
Ordered
之间的区别。 您的类型应该有一个隐式排序。
implicit def comp2ord[A <: Comparable[A]] = new Ordering[A] {
def compare(x : A, y : A) = x compareTo y
}
然后,将这种排序方式转换为 Ordered
的方法:
implicit def ordering2order[A : Ordering](x : A) = new Ordered[A] {
def compare(y : A) = implicitly[Ordering[A]].compare(x, y)
}
不带隐式排序的用法:
scala> val df = new java.text.SimpleDateFormat("yyyy-MM-dd")
df: java.text.SimpleDateFormat = java.text.SimpleDateFormat@f67a0200
scala> TreeSet(df.parse("2011-03-04"), df.parse("2010-05-06"))
<console>:13: error: could not find implicit value for parameter ord: Ordering[java.util.Date]
TreeSet(df.parse("2011-03-04"), df.parse("2010-05-06"))
^
现在有了隐式排序...
scala> implicit def comp2ord[A <: Comparable[A]] = new Ordering[A] {
| def compare(x : A, y : A) = x compareTo y
| }
comp2ord: [A <: java.lang.Comparable[A]]java.lang.Object with Ordering[A]
scala> TreeSet(df.parse("2011-03-04"), df.parse("2010-05-06"))
res1: scala.collection.immutable.TreeSet[java.util.Date] = TreeSet(Fri Mar 04 00:00:00 GMT 2011, Thu May 06 00:00:00 BST 2010)
当然,你还需要将Ordering
隐式转换为Ordered
才能利用scala的比较运算符<
,>=
等:
scala> implicit def ordering2order[A : Ordering](x : A) = new Ordered[A] {
| def compare(y : A) = implicitly[Ordering[A]].compare(x, y)
| }
ordering2order: [A](a: A)(implicit evidence$1: Ordering[A])java.lang.Object with Ordered[A]
scala> df.parse("2010-04-05") < df.parse("2009-01-01")
res2: Boolean = false
如果你的类型 A
是一个实现了原始类型 Comparable
的 Java 类,那么你需要提供一个明确的转换:
implicit def comp2ord(x : DateTime) = new Ordered[DateTime] {
def compare(y : DateTime) = x compareTo y
}
A <: Comparable[A]
吗?在匿名类中调用compareTo
时,您不需要绑定x
,对吧? - DarioComparable[_]
替换为Ordered[DateTime]
并将compareTo
重命名为compare
,因为Ordered
是Comparable
的子类,所以兼容性相当好。 - socDateTime
是在这条评论中。你应该更明确地修改你的问题,因为它对你的问题非常核心。 - oxbow_lakes