本文介绍了Scala隐式转换范围问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
使用此代码:
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
}
我想这样使用它:
val x = register.getZeroFlag + 10
但是我很满意:
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:
- 当寻求与类型
Register
的对象之间的隐式转换时,编译器将查找伴随对象Register
.这就是为什么我们不需要将reg2int
明确纳入定义x
和y
的范围的原因.但是,转换bool2int
确实需要在范围内,因为它没有在Boolean
或Int
随播对象上定义. - 已经在所有对象上定义了方法
+
,以通过scala.Predef
中的隐式any2stringadd
表示字符串连接.定义val z
是非法的,因为字符串连接的隐式优先于reg2int
(在伴随对象中发现的隐含优先级相对较低).但是,定义val z2
起作用是因为我们已经将reg2int
纳入了范围,赋予了它更高的优先级.
- 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.
有关编译器如何搜索隐式信息的更多详细信息,请参见Daniel Sobral的很好的解释: Scala在哪里寻找隐式?
For more details about how the compiler searches for implicits, see Daniel Sobral's very nice explanation: Where does Scala look for implicits?
这篇关于Scala隐式转换范围问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!