这是多个备选方案之间的隐式搜索决策的后续。我将引用其中的代码。
trait A
trait B extends A
caseclass C extends B
trait Tester[-T] { def test (t: T): Boolean }
object Tester {
def test[T](t : T)(implicit tester: Tester[T]) = tester.test(t)
implicit def atester = new Tester[A] { override def test (a: A) = true }
implicit def btester = new Tester[B] { override def test (b: B) = false }
}
val c = C()
Tester.test(c)
我从概念上理解为什么在寻找关于逆变性和特异性的隐含时atester: Tester[A]
选择。btester: Tester[B]
Tester.test(implicit t: Tester[C])
我发现很难看到的是如何具体描述这一点 spec 6.26.3 overloading resolution
。
AFAIK,该规范将需要重载分辨率的标识符或选择 e 分为三类:
- e 用于函数应用程序 e(e1,..., e_m)
- e 用于类型应用程序 e[targs]
- 否则
此外,该规范描述了通过确定一种替代方案比另一种更具体来计算的相对权重。
我首先不明白哪个类别适合替代品。如果是{ Tester[A], Tester[B] }
,那么在我看来 (2) 很可能,但它的规则 -
重载决议再次应用于整个表达式 e[targs]
——看起来又把球扔回去了。而且我也没有发现规范中说明如何比较 A 和 B 的位置。
类似的一个:在同一问题的 2 级答案中,代码被修改,我也在这里引用它:
trait Tester[T] {def test (t: T):Boolean }
object Tester{
def test[T](t: T)(implicit tester: Tester[T]) = tester.test(t)
implicit def atester[T <: A] = new Tester[T] { override def test (a: T) = true }
implicit def btester[T <: B] = new Tester[T] { override def test (b: T) = false }
}
val c = C()
Tester.test(c)
我认为替代方案是两种多态方法:
{ atester[T <: A]: Tester[T], btester[T<: B]: Tester[T] }
. 它看起来属于(1)类。但我不清楚进一步推理。