【问题标题】:Scala implicit conversion scope issuesScala隐式转换范围问题
【发布时间】:2011-08-02 02:45:16
【问题描述】:

获取此代码:

  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

发生了什么?我是否需要定义一个隐含的函数来返回一个布尔值?

【问题讨论】:

    标签: scala implicit implicit-conversion


    【解决方案1】:

    这是一个演示如何使用隐式的示例:

    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 纳入范围,给予它更高的优先级。

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

    【讨论】:

    • 太棒了。这很好地解释了范围界定。
    • 我刚刚发现 Object 上的 ._ 是导入 Object 中定义的东西所必需的。认为这将是“隐含的”(双关语)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 2012-01-02
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    相关资源
    最近更新 更多