由Ordering [T]限定的类型参数T

时间:2013-07-11 15:50:13

标签: scala implicit

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

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
}

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

1 个答案:

答案 0 :(得分:5)

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

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]
{
  // ...
}

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

这样的事情
new MaxHeap[java.lang.Integer]()(new Ordering[java.lang.Number] {
    // ...
  });

此外,Ordering的整体想法是您不必对T施加任何限制。这更灵活,除了其他方面允许对同一个类进行不同的比较。