2011-08-02 14 views
6

Tome este código:Scala alcance de la conversión implícita emite

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 
    } 

quiero usarlo de esta manera:

val x = register.getZeroFlag + 10 

pero me da la bienvenida con:

type mismatch; found : Boolean required: Int 

lo que pasa? ¿Debo definir una función implícita que devuelva un bool?

Respuesta

14

He aquí un ejemplo que muestra cómo utilizar sus implícitos:

cosas
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 
} 

Dos potencialmente no evidentes aquí:

  • En la búsqueda de conversiones implícitas hacia o desde un objeto de tipo Register, el compilador se verá en el objeto complementario Register. Esta es la razón por la cual no necesitamos traer reg2int explícitamente en el alcance para definir x y y. Sin embargo, la conversión bool2int debe estar dentro del alcance porque no está definida en el objeto complementario Boolean o Int.
  • El método + ya está definido en todos los objetos en el sentido de la concatenación de cadenas a través de la implícita en any2stringaddscala.Predef. La definición val z es ilegal porque la implícita para la concatenación de cadenas tiene prioridad sobre reg2int (las implícitas encontradas en los objetos complementarios tienen una prioridad relativamente baja). Sin embargo, la definición val z2 funciona porque hemos llevado reg2int al alcance, lo que le da una mayor prioridad.

Para más detalles acerca de cómo el compilador busca implícitos, muy agradable ver la explicación de Daniel Sobral: Where does Scala look for implicits?

+0

fantástico. Eso explica el alcance realmente bien. –

+0

Acabo de descubrir que el ._ en el objeto es necesario para importar las cosas definidas en el objeto. Pensé que esto sería "implícito" (juego de palabras) – drame

Cuestiones relacionadas