本文介绍了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明确纳入定义xy的范围的原因.但是,转换bool2int确实需要在范围内,因为它没有在BooleanInt随播对象上定义.
  • 已经在所有对象上定义了方法+,以通过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 object Register. This is why we didn't need to bring reg2int explicitly into scope for defining x and y. However, the conversion bool2int does need to be in scope because it's not defined on the Boolean or Int companion object.
  • The method + is already defined on all objects to mean string concatenation via the implicit any2stringadd in scala.Predef. The definition val z is illegal because the implicit for string concatenation takes priority over reg2int (implicits found in companion objects are relatively low priority). However, the definition val z2 works because we've brought reg2int 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隐式转换范围问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 05:08