2013-07-11 20 views
5

Wdrażając sortable strukturę danych, myślałem zrobić coś takiego:Rodzaj parametr T ograniczony zamawiania [T]

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

Ale to nie działa dla typów takich jak MaxHeap [Int]. W standardowej bibliotece kolekcji typ elementu T kolekcji nie jest ograniczony. Zamiast tego zapewnia się tryb niejawny dla metod, które wymagają przekształcenia T na zamówienie [T], np.

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 
} 

Moje pytanie jest, jeśli istnieje wiele metod w mojej klasie/cechy obejmujące porównanie, czy istnieje sposób, aby określić typ elementu klasa/cecha, aby być porównywalne, tak że nie trzeba zadeklarować implicits dla tych, metody?

Odpowiedz

5

Można zadeklarować niejawny parametr, który określa kolejność, a następnie można go używać we wszystkich metod:

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

Jeśli jest to cecha, to nie mogą przyjmować parametr, ale można zadeklarować ją jako wartość niejawny:

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

a następnie każdej klasy, która używa może potrwać niejawny parametr, który zastępuje go:

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

Aktualizacja: Dla niektórych technical reasonsOrdering nie jest kontrawariantny. Dlatego użyłem Ordering[_ >: T], ponieważ pozwala to na większą elastyczność. Możesz użyć porządku zdefiniowanego dla nadklasy T. Można oczywiście użyć tylko cmp: Ordering[T], ale wtedy nie można zrobić rzeczy jak

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

Również cała idea Ordering jest to, że nie trzeba nakładać żadnych ograniczeń na T. Jest to bardziej elastyczne i między innymi pozwala na różne porównania dla tej samej klasy.

+0

Dziękuję @Petr. Ale w ten sposób 'T' nie jest wymuszane, aby być porównywalnym, jak gdyby był ograniczony na liście parametrów typu. Każde 'T' zrobi, pod warunkiem, że jest podany domniemany. – cfchou

+0

'Zamawianie [_>: T]' jest techniką, której wcześniej nie widziałem. Zastanawiam się jednak, dlaczego nie użyć "Zamawiania [T]". Dogodne operatory, takie jak '>' pośrednio dostarczone przez 'Ordering.Implicits', nie wydają się działać z' Zamawianiem [_>: T] '. – cfchou

+0

@ cfchou Aktualizuję odpowiedź, aby odpowiedzieć na twoje komentarze. –

Powiązane problemy