问题描述
在以下Scala难题者的代码中,隐含的内容似乎没有冲突,因为TestAlarmHandler
更具体.我不明白这个解释.为什么TestAlarmHandler
比DefaultAlarmHandler
更具体?
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!
推荐答案
TestAlarmHandler
比DefaultAlaramHandler
更具体,因为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语言规范指定找到多个合格参数的情况下的处理方式,如下所示(请注意,由于TestAlarmHandler
和DefaultAlarmHandler
均已由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._
):
第 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一样具体,则为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.
TestAlarmHandler
在DefaultAlarmHandler
上的相对权重为1,而DefaultAlarmHandler
在TestAlarmHandler
上的相对权重为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.
TestAlarmHandler
比DefaultAlaramHandler
更具体,因为相对于DefaultAlarmHandler
的相对权重TestAlarmHandler
大于反之.
TestAlarmHandler
is more specific than DefaultAlaramHandler
because the relative weight TestAlarmHandler
over DefaultAlarmHandler
is greater than that of the inverse.
这篇关于Scala中的低优先级和高优先级隐式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!