在实现可排序的数据结构时,我正在考虑做这样的事情:
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
}
我的问题是,如果我的类/特性中涉及比较的方法很多,有没有办法指定类/特征的元素类型是可比较的,这样我就不需要声明这些方法的含义?
答案 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
施加任何限制。这更灵活,除了其他方面允许对同一个类进行不同的比较。