2011-08-02 4 views
6

Prenez ce code:Scala champ de conversion implicite émet

class Register(var value:Int = 0) { 
     def getZeroFlag() : Boolean = (value & 0x80) != 0 
    } 

    object Register { 
     implicit def reg2int(r:Register):Int = r.value 
     implicit def bool2int(b:Boolean):Int = if (b) 1 else 0 
    } 

Je veux l'utiliser comme ceci:

val x = register.getZeroFlag + 10 

mais je suis accueilli avec:

type mismatch; found : Boolean required: Int 

ce qui se passe? Ai-je besoin de définir une fonction implicite prenant une fonction bool?

Répondre

14

Voici un exemple montrant comment utiliser vos implicits:

object Test { 
    val register = new Register(42) 
    val x = 1 + register // implicitly calling reg2int from companion object 
    val y = register - 1 // same 
    // val z = register + 1 // doesn't work because "+" means string concatenation 

    // need to bring bool2int implicit into scope before it can be used 
    import Register._ 
    val w = register.getZeroFlag() + 2 // this works now 
    val z2 = register + 1 // works because in-scope implicits have higher priority 
} 

Deux choses non évidente ici:

  • Lorsque l'on cherche des conversions implicites ou d'un objet de type Register, le compilateur va regarder dans l'objet compagnon Register. C'est pourquoi nous n'avons pas eu besoin de mettre explicitement reg2int dans la portée pour définir x et y. Toutefois, la conversion bool2int doit être dans la portée car elle n'est pas définie sur l'objet compagnon Boolean ou Int.
  • La méthode + est déjà définie sur tous les objets pour signifier la concaténation de chaîne via le any2stringadd implicite dans scala.Predef. La définition val z est illégale car l'implicite pour la concaténation de chaîne est prioritaire sur reg2int (les implicits trouvés dans les objets compagnons sont de priorité relativement faible). Cependant, la définition val z2 fonctionne parce que nous avons mis reg2int dans la portée, en lui donnant une priorité plus élevée.

Pour plus de détails sur la façon dont les recherches du compilateur pour implicits, voir explication très belle Daniel Sobral: Where does Scala look for implicits?

+0

fantastique. Cela explique vraiment la portée. –

+0

J'ai juste compris que le ._ sur l'objet est nécessaire pour importer les choses définies dans l'objet. Pensé que ce serait "implicite" (jeu de mots) – drame

Questions connexes