【问题标题】:low priority and high priority implicits in scalascala中的低优先级和高优先级隐含
【发布时间】:2017-11-18 01:37:22
【问题描述】:

在以下来自 Scala 的谜题的代码中,似乎没有隐含冲突,因为 TestAlarmHandler 更具体。虽然我没看懂解释。为什么TestAlarmHandlerDefaultAlarmHandler 更具体?

object Scanner {
  trait Console { def display(item: String) }
  trait AlarmHandler extends (() => Unit)
  def scanItem(item: String)(implicit c: Console) {
    c.display(item)
  }
  def hitAlarmButton()(implicit ah: AlarmHandler) { ah() }
}


class OperatingMode {
  implicit val ConsoleRenderer = new Scanner.Console {
    def display(item: String) { println(s"Found a ${item}") }
  }
  implicit val DefaultAlarmHandler = new Scanner.AlarmHandler {
    def apply() { println("ALARM! ALARM!") }
  }
}
object NormalMode extends OperatingMode
object TestMode extends OperatingMode {
  override implicit val ConsoleRenderer = new Scanner.Console {
    def display(item: String) { println("Found a detonator") }
  }
  implicit val TestAlarmHandler = new Scanner.AlarmHandler {
    def apply() { println("Test successful. Well done!") }
  }
}
import NormalMode._
scala> Scanner scanItem "knife"
Found a knife
scala> Scanner.hitAlarmButton()
ALARM! ALARM!
import TestMode._
scala> Scanner scanItem "shoe"
Found a detonator
scala> Scanner.hitAlarmButton()
Test successful. Well done!

【问题讨论】:

    标签: scala implicit


    【解决方案1】:

    TestAlarmHandlerDefaultAlaramHandler 更具体,因为 TestAlarmHandler 是在一个匿名类中定义的,该类派生自定义 DefaultAlarmHandler 的类 OperatingMode


    正式地,the Scala Language Specification 指定当找到多个符合条件的参数时如何处理一个案例,如下所示(注意TestAlarmHandlerDefaultAlarmHandler 都是符合条件的,因为它们已被import TestMode._ 导入):

    如果有多个符合条件的参数与隐式参数的类型匹配,则将使用静态重载决策规则选择最具体的参数。

    6.26.3 Overloading Resolution 部分根据相对权重的概念定义了更具体的概念:

    替代A相对于替代B的相对权重是一个从0到2的数字,定义为

    • 如果 A 与 B 一样具体,则为 1,否则为 0,并且
    • 如果 A 在派生自定义 B 的类或对象的类或对象中定义,则为 1,否则为 0。

    TestAlarmHandlerDefaultAlarmHandler 的相对权重为 1,而 DefaultAlarmHandlerTestAlarmHandler 的相对权重为 0。请注意,TestAlarmHandler 定义在一个匿名类中,该类派生自定义 @ 的类 OperatingMode 987654337@。第一条规则在解决方法重载时值得关注,但在这里不相关。

    如果 A 相对于 B 的相对权重大于 B 相对于 A 的相对权重,则备选 A 比备选 B更具体

    TestAlarmHandlerDefaultAlaramHandler 更具体,因为TestAlarmHandler 相对于DefaultAlarmHandler 的相对权重大于反之。

    【讨论】:

      【解决方案2】:

      那是因为 TestMode 是 OperationMode 的子类,scala 首先在 TestMode 的范围内查找隐式,只有在没有找到时才会在层次结构中查找。

      【讨论】:

        猜你喜欢
        • 2012-09-19
        • 2020-12-21
        • 2020-07-06
        • 2014-11-26
        • 2013-02-13
        • 1970-01-01
        • 2021-05-14
        • 2020-03-22
        • 2011-11-27
        相关资源
        最近更新 更多