2

有没有办法在选择最具体的类型类中拥有多个合适的替代方案,而不产生发散的隐式扩展?它看起来像这样

trait A

trait B extends A

case class 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)

我希望这产生错误,因为在继承层次结构中 C 更接近 B 而不是 A 。

4

2 回答 2

2

我将提供一些解释为什么它会以这种方式工作 - 另一个答案有一个可能的解决方法。

Tester[A]被选中的原因与逆变Tester[B]的类型T有关。Tester[-T]这意味着 forTester[A]要成为 , 的子类Tester[B]A必须是的超类B- 就像您的代码示例所示。

因此,当方法test(带有隐式参数)需要 的子类型时Tester[C],替代方案将是Tester[B](的子类Tester[C])和Tester[A](也是 的子类Tester[C],但更具体)。这就是为什么根据选择最具体类型的规则,Tester[A]被选中的原因。

如果有一个class D extends C, 和一个返回的隐式函数Tester[D], if 将不是参数解析的一部分Tester[C]

这里有更多关于它的信息。

于 2013-04-16T19:25:05.347 回答
0

似乎这有帮助

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
  }

}

有异议吗?

于 2013-04-16T21:38:52.523 回答