6

在实现可排序的数据结构时,我正在考虑做这样的事情:

trait MaxHeap[T <: Ordering[T]] {
    def insert(e: T): Unit
    ...
}

但这不适用于像 MaxHeap[Int] 这样的类型。在标准集合库中,集合的元素类型 T 是无界的。相反,为需要将 T 转换为 Ordering[T] 的方法提供了隐式,例如

trait Seq[+A] extends ... {
    // it's Ordering[B], not Ordering[A], but the idea is the same.
    def max[B >: A](implicit cmp: Ordering[B]): A
}

我的问题是,如果我的类/特征中有很多涉及比较的方法,有没有办法指定类/特征的元素类型是可比较的,这样我就不需要为这些方法声明隐含?

4

1 回答 1

7

您可以声明一个定义排序的隐式参数,然后您可以在所有方法中使用它:

class MaxHeap[T](implicit cmp: Ordering[_ >: T]) ...

如果它是一个特征,它不能带参数,但你可以将它声明为一个隐式值:

trait Heap[T] {
  implicit protected val cmp: Ordering[_ >: T];
  // ... use cmp in your methods ...
}

然后每个使用它的类都可以采用一个隐式参数来覆盖它:

class MaxHeap[T](implicit override protected val cmp: Ordering[_ >: T])
  extends Heap[T]
{
  // ...
}

更新:由于某些技术原因 Ordering不是逆变的。这就是我使用 的原因Ordering[_ >: T],因为它允许更大的灵活性。您可以使用为 的超类定义的排序T。你当然可以使用 just cmp: Ordering[T],但是你不能做类似的事情

new MaxHeap[java.lang.Integer]()(new Ordering[java.lang.Number] {
    // ...
  });

此外,整个想法Ordering是您不必对T. 这更灵活,除其他外,还允许对同一类进行不同的比较。

于 2013-07-11T16:12:02.727 回答