scala 解决冲突隐含值的规则是什么 [英] What are scala's rules for resolving conflicting implicit values
问题描述
给定以下代码:
/**
* 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 的输出是:
The output for scala 2.11 is:
b class = DEC - EC
c class = DEC - EC
c class = EC
我希望它是:
b class = DEC - EC
c class = EC
c class = EC
因为隐式 val _ec
被声明为更接近"whichEC
中对 usesEC
的调用.为什么会发生这种情况?另外,我如何才能强制 _ec
在 C.whichEC
中隐式使用?
Because the implicit val _ec
is declared "closer" to the call to usesEC
in whichEC
. Why does this happen? Also,how I might be able to force _ec
to be used implicitly in C.whichEC
?
推荐答案
子类型胜:
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 中定义Scala 语言规范:
The rules for resolution of implicit parameters are defined in §7.2 of the Scala Language Specification:
如果有多个符合条件的参数与隐式参数的类型匹配,则将使用静态重载解析规则选择一个最具体的参数.
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.这里的类型 A <: B
给予替代子类 A
相对于替代超类 的
,使 1
的相对权重BA
比 B
更具体.
This links to §6.26.3 which deals with type inference. Here a type A <: B
gives the alternative sub-class A
a relative weight of 1
over the alternative super-class B
, making A
more specific than B
.
一般来说,正如评论所暗示的那样,您应该避免将多个不合格的成员(无前缀,即在默认位置找到的隐式值,例如通过伴随对象)引入作用域.
In general, as the comment suggests, you should avoid bringing multiple unqualified members (prefix-less, i.e. implicit values that are found in default locations for example through companion objects) into scope.
这篇关于scala 解决冲突隐含值的规则是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!