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

怎么了?我是否需要定义一个隐式的函数返回一个bool?

解决方法

这是一个演示如何使用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 
}

这里有两个可能不明显的事情:

>当寻求与Register类型的对象进行隐式转换时,编译器将查找伴随对象Register.这就是为什么我们不需要将reg2int明确地引入定义x和y的范围.但是,转换bool2int确实需要在范围内,因为它没有在Boolean或Int伴随对象上定义.
>该方法已在所有对象上定义为通过scala.Predef中的隐式any2stringadd表示字符串连接.定义val z是非法的,因为字符串连接的隐含优先于reg2int(在伴随对象中发现的隐含是相对较低的优先级).但是,定义val z2是有效的,因为我们已将reg2int引入范围,从而赋予其更高的优先级.

有关编译器如何搜索implicits的更多详细信息,请参阅Daniel Sobral的非常好的解释:Where does Scala look for implicits?

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...