2010-12-02 4 views
3

Je crée quelques classes paramétrées C [T] et je veux faire certaines exigences des caractéristiques du type T pour pouvoir être un paramètre de ma classe. Ce serait simple si je voulais juste dire que T héritait de traits ou de classes (comme nous le faisons avec Ordering). Mais je veux aussi mettre en place certaines fonctions. Par exemple, j'ai vu que de nombreux types prédéfinis implémentent MinValue et MaxValue, je voudrais que mon type T les implémente aussi. J'ai reçu quelques conseils pour définir simplement une fonction implicite. Mais je ne voudrais pas que tous les utilisateurs soient obligés d'implémenter cette fonction pour ceux-ci quand elle est déjà implémentée. Je pourrais les implémenter à mon code aussi, mais il semble juste que ce soit une mauvaise solution rapide. Par exemple, lors de la définition de heaps, je voudrais autoriser les utilisateurs à construire un tas vide. Dans ces cas, je veux inicialiser la valeur avec la valeur minimale que le type T pourrait avoir. Évidemment, ce code ne fonctionne pas. Je voudrais aussi recevoir quelques conseils sur les références Scala 2.8 en ligne vraiment bonnes.Scala: Comment faire des exigences de type parametres de classes génériques?

+0

Pouvez-vous clarifier ce que vous cherchez avec un exemple de (pseudo) code? Qu'avez-vous essayé, et pourquoi cela n'a-t-il pas fonctionné? –

+0

Voir http://stackoverflow.com/questions/68074/good-way-to-learn-scala pour beaucoup de liens vers les ressources de Scala. –

+0

Essayez d'en savoir plus sur les limites de type. Les exemples de code sont là: https://gist.github.com/257758/47f06f2f3ca47702b3a86c76a5479d096cb8c7ec –

Répondre

5

Un tas de choses, toutes vaguement liées en raison du partage de quelques méthodes (mais avec des types de retour différents). Sûr ressemble à un polymorphisme ad hoc pour moi!

rouler sur la classe de type ...

class HasMinMax[T] { 
    def maxValue: T 
    def minValue: T 
} 

implicit object IntHasMinMax extends HasMinMax[Int] { 
    def maxValue = Int.MaxValue 
    def minValue = Int.MinValue 
} 

implicit object DoubleHasMinMax extends HasMinMax[Double] { 
    def maxValue = Double.MaxValue 
    def minValue = Double.MinValue 
} 

// etc 

class C[T : HasMinMax](param : T) { 
    val bounds = implicitly[HasMinMax[T]] 
    // now use bounds.minValue or bounds.minValue as required 
} 

MISE À JOUR

La notation [T : HasMinMax] est un contexte lié, et le sucre syntaxique pour:

class C[T](param : T)(implicit bounds: HasMinMax[T]) { 
    // now use bounds.minValue or bounds.minValue as required 
} 
+0

Cela fonctionne bien pour les fonctions normales. Mais j'ai des problèmes pour l'utiliser à l'intérieur d'un constructeur ... On dit que les limites n'ont pas été trouvées – Bruna

+0

J'ai ajouté l'extension à ma définition, ça devrait marcher pour vous –

2

Vous pouvez utiliser des bornes de type:

trait Base 

class C[T <: Base] 

permettant C à paramétrées avec tout type T qui est un sous-type de Base.

Ou vous pouvez utiliser des paramètres implicites pour exprimer les exigences:

trait Requirement[T] { 
    def requiredFunctionExample(t: T): T 
} 

class C[T](implicit req: Requirement[T]) 

Ainsi, les objets de la classe C ne peuvent être construits s'il existe une mise en œuvre du trait Requirement pour le type T vous souhaitez les paramètrer avec . Vous pouvez placer des implémentations de Requirement pour différents types T dans, par exemple, un objet de package, en les mettant ainsi à portée chaque fois que le package correspondant est importé.

+0

Ok! Mais ce n'est pas ce que je cherche. Je ne veux pas redéfinir MinValue et MaxValue dans un trait quand il est déjà défini. Plus que cela, je voudrais, Int, Double, Char ... être ces paramètres T mais aucun d'eux ne prolonge le trait que je crée. – Bruna

+0

Le problème est que 'MinValue' et' MaxValue' n'ont pas les mêmes types pour 'Int',' Char', ..., ils ont des signatures différentes, donc ce sont des méthodes différentes. Cela signifie que vous devrez probablement créer un trait d'exigence avec une méthode abstraite renvoyant, par exemple, Tout, puis le redéfinir pour les types de base. J'espère que je vous ai bien compris .. – axel22

Questions connexes