Scala中的低优先级和高优先级隐式 [英] low priority and high priority implicits in scala

查看:172
本文介绍了Scala中的低优先级和高优先级隐式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下Scala难题者的代码中,隐含的内容似乎没有冲突,因为TestAlarmHandler更具体.我不明白这个解释.为什么TestAlarmHandlerDefaultAlarmHandler更具体?

In following code from Scala's puzzlers, it seems that there is no conflict in implicits because TestAlarmHandler is more specific. I didn't understand the explanation though. Why is TestAlarmHandler is more specific than DefaultAlarmHandler?

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!

推荐答案

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

TestAlarmHandler is more specific than DefaultAlaramHandler because TestAlarmHandler is defined in an anonymous class which is derived from class OperatingMode defining DefaultAlarmHandler.

Scala语言规范指定找到多个合格参数的情况下的处理方式,如下所示(请注意,由于TestAlarmHandlerDefaultAlarmHandler均已由import TestMode._导入,因此它们都是合格的):

Formally, the Scala Language Specification specifies how to handle a case when more than one eligible arguments are found, as follows (note that both TestAlarmHandler and DefaultAlarmHandler are eligible because they have been imported by import TestMode._):

如果有几个与隐式参数类型匹配的合格参数,则将使用静态重载解析规则选择一个最具体的参数.

If there are several eligible arguments which match the implicit parameter's type, a most specific one will be chosen using the rules of static overloading resolution.

6.26.3重载分辨率根据相对权重的概念来定义更具体的概念:

Section 6.26.3 Overloading Resolution defines the concept of being more specific in terms of the concept of relative weight:

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

The relative weight of an alternative A over an alternative B is a number from 0 to 2, defined as the sum of

  • 如果A与B一样具体,则为1,否则为0,
  • 如果从定义B的类或对象派生的类或对象中定义了A,则为1,否则为0.
  • 1 if A is as specific as B, 0 otherwise, and
  • 1 if A is defined in a class or object which is derived from the class or object defining B, 0 otherwise.

TestAlarmHandlerDefaultAlarmHandler上的相对权重为1,而DefaultAlarmHandlerTestAlarmHandler上的相对权重为0.请注意,TestAlarmHandler在匿名类中定义,该匿名类派生自定义DefaultAlarmHandler.解决方法重载时,第一个规则值得关注,但此处不相关.

The relative weight of TestAlarmHandler over DefaultAlarmHandler is 1 while that of DefaultAlarmHandler over TestAlarmHandler is 0. Note that TestAlarmHandler is defined in an anonymous class which is derived from class OperatingMode defining DefaultAlarmHandler. The first rule is of concern when resolving method overloading, but not relevant here.

如果A相对于B的相对权重大于B相对于A的相对权重,则替代A比替代B更具特异性.

An alternative A is more specific than an alternative B if the relative weight of A over B is greater than the relative weight of B over A.

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

TestAlarmHandler is more specific than DefaultAlaramHandler because the relative weight TestAlarmHandler over DefaultAlarmHandler is greater than that of the inverse.

这篇关于Scala中的低优先级和高优先级隐式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆