2010-11-26 6 views
6

J'essaie de réécrire https://gist.github.com/319827 à Scala. Mais je ne peux pas le compiler. Quelle est la syntaxe correcte?Scala, extension générique avancée

Erreur Je AllWays obtenir:

type de classe nécessaire, mais java.util.Comparator [_>: java.lang.Comparable [java.lang.Object]] trouvé

source:

package v6ak.util 

import java.util.Comparator 

object NaturalComparator extends Comparator[_ >: Comparable[Object]]{ 

    override def compare(o1:Comparable[Object], o2:Comparable[Object]) = { 
     if(o1==null || o2==null){ 
      throw new NullPointerException("Comparing null values is not supported!"); 
     } 
     o1.compareTo(o2); 
    } 

} 

Répondre

2

Je suis retourné au problème avec plus d'expérience et solved it, bien que je pense que c'est peut être mieux.

package v6ak.util 

import java.util.Comparator 

object NaturalComparator extends Comparator[Comparable[Any]]{ 

    def apply[T]() = asInstanceOf[Comparator[T]] 

    override def compare(o1:Comparable[Any], o2:Comparable[Any]) = { 
     if(o1 == null || o2 == null){ 
      throw new NullPointerException("Comparing null values is not supported!") 
     } 
     o1 compareTo o2 
    } 

} 
+0

ce n'est pas le type de sécurité, vous pourriez avoir quelques erreurs d'exécution ... – linehrr

+0

vous avez raison, la méthode d'application n'applique rien comme >. Mais cela pourrait être changé. – v6ak

14

A extends B est écrit dans A<:B scala pas A>:B

par la voie, le système de type scala est assez puissant pour éviter l'utilisation de l'objet (AnyRef dans scala) dans votre code

package v6ak.util 

import java.util.Comparator 

class NaturalComparator[T <: Comparable[T]] extends Comparator[T] { 
    override def compare(o1: T, o2: T) = { 
    if (o1 == null || o2 == null) { 
     throw new NullPointerException("Comparing null values is not supported!"); 
    } 
    o1.compareTo(o2); 
    } 
} 

object StringComparator extends NaturalComparator[String] 

object Examples { 
    StringComparator.compare("a", "b") 
    StringComparator.compare(2, "b") // error 
} 
+0

Eh bien, ce n'est pas exactement le code que je veux. Je déteste vraiment la spécialisation (comme la spécialisation dans ObjectPascal). – v6ak

+0

Vous pouvez écrire du code moins spécialisé mais vous perdrez la sécurité de type au moment de la compilation. Voulez-vous vraiment être autorisé à écrire du code pour comparer 'Date' avec' File' qui échouera seulement à l'exécution? – shellholic

+0

Hmm, mais ce n'est pas le cas du code Java original. Je pense que je peux écrire quelque chose de similaire au code Java dans Scala, mais ce n'est pas très sympa. – v6ak

2

Eh bien, vous avez fait des dégâts avec cette version java. Notez que vous créez une instance de Comparateur < Objet < comparable et que vous l'attribuez à la valeur avec un caractère générique - pour quoi faire? Vous n'attribuez rien d'autre à cette variable. Ne pas parler que votre getInstance définit également wildecards, alors qu'il retourne tout le même < Comparator Comparable < Objet >>

Alors:

object NaturalComparator extends Comparator[Comparable[Object]]{ 
    override def compare(o1:Comparable[Object], o2:Comparable[Object]) = { 
     if(o1 == null || o2 == null){ 
      throw new NullPointerException("Comparing null values is not supported!"); 
     } 
     o1.compareTo(o2); 
    } 
} 
+0

C'est un moyen qui permet d'avoir une seule instance et de l'utiliser pour différents types. Il est de facto compatible, mais Java n'a pas le pouvoir de l'expliquer sans @SuppressWarning. Je ne pense pas que ce soit un gâchis. Votre code n'est pas le code que je veux. Le code suivant ne fonctionne pas: https://gist.github.com/d2d24794f61b5afb7d57 – v6ak