在实现可排序的数据结构时,我正在考虑执行以下操作:

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
}


我的问题是,如果我的类/特征中有很多涉及比较的方法,是否有一种方法可以指定类/特征的元素类型具有可比性,从而无需为这些方法声明隐式?

最佳答案

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

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 reasonsOrdering而言,它们不是互变的。这就是为什么我使用Ordering[_ >: T]的原因,因为它允许更大的灵活性。您可以使用为T的超类定义的排序。您当然可以只使用cmp: Ordering[T],但是您不能做类似的事情

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


同样,Ordering的整个思想是您不必对T施加任何约束。这更加灵活,并且除其他功能外,还可以针对同一类进行不同的比较。

关于scala - 类型参数T受Ordering [T]限制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17597961/

10-10 17:24