给出以下代码:
/**
* Created by danap on 12/8/15.
*/
object ImplicitTest {
trait EC {
override def toString : String = s"EC"
}
trait DEC extends EC {
def sub : EC
override def toString : String = s"DEC - $sub"
}
def usesEC(implicit ec : EC) = ec.toString
class B(implicit val dec: DEC) {
def whichEC = usesEC
}
class C(implicit val dec: DEC) {
implicit val _ec = dec.sub
def whichEC = usesEC
def whichECExplicit = usesEC(_ec)
}
def main(args:Array[String]): Unit = {
implicit val dec : DEC = new DEC {
val sub = new EC {}
}
val b = new B
val c = new C
println(s"b class = ${b.whichEC}")
println(s"c class = ${c.whichEC}")
println(s"c class = ${c.whichECExplicit}")
}
}
scala 2.11的输出是:
b class = DEC - EC
c class = DEC - EC
c class = EC
我原以为:
b class = DEC - EC
c class = EC
c class = EC
因为隐式val _ec
被宣布为“更接近”usesEC
中对whichEC
的调用。为什么会这样?另外,我如何强制_ec
隐式使用C.whichEC
?
答案 0 :(得分:2)
子类型获胜:
class Super { override def toString = "Super" }
class Sub extends Super { override def toString = "Sub" }
// does not compile - ambiguous
object Test1 {
implicit val s1 = new Super
implicit val s2 = new Super
println(implicitly[Super])
}
// does not compile - ambiguous
object Test2 {
implicit val s1 = new Sub
implicit val s2 = new Sub
println(implicitly[Super])
}
object Test3 {
implicit val s1 = new Super
implicit val s2 = new Sub
println(implicitly[Super])
}
Test3 // 'Sub'
隐式参数的解析规则在§7.2 of the Scala Language Specification:
中定义如果有几个符合条件的参数与隐式参数的类型匹配,则将使用静态重载分辨率的规则选择最具体的参数。
这链接到§6.26.3,它涉及类型推断。此处,A <: B
类型为备用超类A
提供了替代子类1
相对权重B
,使A
更多具体而不是B
。
通常,正如评论所暗示的那样,您应该避免将多个不合格的成员(无前缀,即默认位置中的隐式值,例如通过伴随对象)带入范围。