2010-12-01 2 views
5

J'ai des problèmes pour bien comprendre comment utiliser les manifestes.Scala: Problèmes avec l'effacement sur la fonction d'égalisation prioritaire pour les classes paramétrées

Voilà mon problème: J'ai creat une nouvelle classe paramétrisé C et tryed surchargent equals comme ceci:

override def equals(that:Any)=that match{ 
case that:C[T] => true /*do smth else not relevant*/ 
case _ => false 
} 

Bien sûr, je reçois le « avertissement: type argument non variables T dans le modèle de type C [T] est décochée puisqu'elle est éliminée par effacement ". Je tryied donc en utilisant comme je manifeste utilise dans de nombreuses autres fonctions:

override def equals(that:Any)(implicit manifest:Manifest[T])=that match{ 
case that:C[T] => true 
case _ => false 
} 

Mais j'ai reçu la « erreur: méthode est égale à rien overrides » message.

Je ne sais pas comment résoudre ce problème. Quelqu'un pourrait-il m'aider s'il vous plaît?

Répondre

5

Vous ne pouvez pas le réparer. Bienvenue dans les joies d'une interopération fluide avec Java. La seule façon d'améliorer est égale à def equals(x: Any): Boolean est d'écrire une méthode différente. J'essaie toujours de convaincre Martin que nous devrions implémenter == dégoûter différemment, en visant quelque chose comme "def decentEquals [T] (x: T) (equiv implicite: Equiv [T])" avec implicits par défaut et Les méthodes de pont pour le rendre transparent, sauf si vous vous souciez, mais il pense que les tests d'égalité ne devrait pas être plus lent.

+0

Merci. Je me fous de java, donc ce serait un plaisir de ne pas avoir tous ces problèmes. J'ai l'habitude de travailler avec Lisp et Haskell, donc je ne peux pas comprendre pourquoi Scala est si bavarde. – Bruna

+1

Oui, c'est dommage que les relations d'équivalence ne soient pas connectables en scala.Je ne suis pas d'accord avec Martin; la plupart des gens ne se soucient pas de la performance (ou du moins, ils ne devraient pas) à ce point –

-1
override def equals(that:Any)= { 
    that match{    
     case that:C[x] => true 
     case _ => false          
    } 
    } 

va compiler, mais je ne pense pas qu'il fasse ce que vous voulez. Vous essayez de voir si les paramètres de type correspondent (je suppose), mais je ne sais pas comment (ou si) vous pouvez le faire. (Edit: en lisant plus de littérature, je pense que vous ne pouvez pas, vous ne pouvez pas, pour des raisons évidentes, remplacer une fonction non-manifest-aware avec une fonction manifest-aware).

4

Juste un complément à @extempore la réponse; il est tout à fait possible d'écrire null-safe équivaut à des méthodes qui peuvent être de type sécurisé. Jetez un oeil à ScalazIdentity (and examples)

new Fruit ≠ new Orange //does not compile 
new Apple ≟ new Apple //compiles! 

En se basant sur les types, il faudrait une paramétrisation être égale aussi (c.-à-C[T] == C[U] iff T =:= U


Bien sûr, le problème à essayer de passer outre une méthode :

def foo(bar : Bar) : Baz 

Avec ceci:

def foo(bar : Bar) (implicit bat : Bat) : Baz 

Est-ce cela ne constitue pas la dérogation. Parce que la méthode a une signature différente vous avez surchargé la méthode à la place. C'est pourquoi il est bon que scala nécessite le modificateur override: sinon vous ne pourriez pas avoir remarqué que le code ne faisait pas ce que vous pensiez qu'il était!

+0

'[T] == C [U] ssi C =: = U' n'est pas censé être' T =: = U' ? – pedrofurla

+0

Merci - le froid ralentit mon cerveau –

Questions connexes