2009-04-25 5 views
5

J'ai une classe que je voudrais utiliser dans une scala.collection.mutable.PriorityQueue, mais je ne veux pas la faire classer [A] juste pour ce seul but. Je ne considère pas la commande que je veux utiliser en ce qui concerne PriorityQueue comme l'ordre naturel de la classe. Donc, dans ma PriorityQueue, je voudrais que les valeurs soient ordonnées par 'séquence'. Cependant, le fait que deux objets aient la même séquence ne les rend pas naturellement égaux puisque le contenu de leurs «valeurs» peut être différent.Scala: Existe-t-il un moyen d'utiliser PriorityQueue comme je le ferais en Java?

C'est ici qu'en Java, il est intéressant de pouvoir fournir un autre objet Comparator à la PriorityQueue. Mon comparateur ordonne simplement les objets par rapport à leur «séquence» et ignore leurs «valeurs».

La classe PriorityQueue doit être paramétrées avec un « A <% Ordonné [A] »

class PriorityQueue[A <% Ordered[A]] extends ... 

D'après ce que j'ai lu, cela signifie ma classe doit se prolonger Ordonné [A] ou je dois fournir une Conversion "implicite def" en Ordered [A], qui, honnêtement, se sent inélégant. La solution Java semble plus «fonctionnelle», ce qui me permet de passer un objet semblable à une fonction de Comparateur au lieu de me forcer dans une hiérarchie de classe ou de monotyper ma classe. Je me rends compte qu'il existe des alternatives à l'utilisation de PrioirityQueue, mais je pense que je suis peut-être heurter contre la courbe d'apprentissage Scala ici et je ne veux pas abandonner sans explorer complètement cette décision de conception.

Est-ce juste une décision malheureuse dans la bibliothèque Scala ou est-ce que je ne comprends pas une sorte de convention d'appel qui rend PriorityQueue plus utilisable et «fonctionnel»?

Merci

Répondre

9

La syntaxe

class PriorityQueue[A <% Ordered[A]] ... 

est vraiment juste une sucrage lumière au-dessus de

class PriorityQueue[A]()(implicit convert: A => Ordered[A]) ... 

Cela signifie que vous pouvez écrire votre propre méthode A => Ordonné [A]

case class Foo(n: Int) 
def orderedFoo(f: Foo): Ordered[Foo] = new Ordered[Foo] { 
    def compare(other: Foo) = f.n.compare(other.n) 
} 

Et passez-le manuellement dans votre constructeur PriorityQueue

new PriorityQueue[Foo]()(orderedFoo) 
3

La fonction de conversion de A à Ordonné [A] peut jouer le rôle du comparateur Java. La fonction doit être visible uniquement dans la portée où vous créez PriorityQueue, de sorte qu'elle ne devienne pas "naturelle" pour votre objet.

2

La combinaison des deux (bonnes) réponses avant celui-ci dans le code compilable:

object o { 
    case class Foo(n: Int) 
    implicit def orderedFoo(f: Foo): Ordered[Foo] = new Ordered[Foo] { 
    def compare(other: Foo) = f.n.compare(other.n) 
    } 

    val x = new scala.collection.mutable.PriorityQueue[Foo]() 
} 

Son exemple ne compilerait pas pour vous parce que (je suis en supposant) vous l'a jeté au compilateur-est. Vous ne pouvez pas compiler des méthodes de niveau supérieur dans Scala, tout doit être dans un objet.

2

In scala 2.8.0, le PriorityQueue change à

class PriorityQueue[A](implicit ord : Ordering[A]) 

Et la commande [A] Scala est similaire à Java Comparator

Questions connexes