Scala implicit conversion scope issues
Take this code:
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
}
I want to use it like so:
val x = register.getZeroFlag + 10
but I am greeted with:
type mismatch; found : Boolean required: 开发者_运维技巧Int
What goes? Do I need to define a implicit taking a function that returns a bool?
Here's an example demonstrating how to use your 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
}
Two potentially non-obvious things here:
- When seeking implicit conversions to or from an object of type
Register
, the compiler will look in the companion objectRegister
. This is why we didn't need to bringreg2int
explicitly into scope for definingx
andy
. However, the conversionbool2int
does need to be in scope because it's not defined on theBoolean
orInt
companion object. - The method
+
is already defined on all objects to mean string concatenation via the implicitany2stringadd
inscala.Predef
. The definitionval z
is illegal because the implicit for string concatenation takes priority overreg2int
(implicits found in companion objects are relatively low priority). However, the definitionval z2
works because we've broughtreg2int
into scope, giving it higher priority.
For more details about how the compiler searches for implicits, see Daniel Sobral's very nice explanation: Where does Scala look for implicits?
精彩评论