无法理解为什么`trait Hello [+ A] {def test [B<:A]}`无法编译

时间:2014-05-02 04:38:10

标签: scala generics contravariance type-systems

我可以理解为什么以下代码无法编译:

trait Hello[+A] {
    def test[B<:A](x: B)
}

由于:

val child: Hello[String] = new Hello[String] {
    def test[B <: String](x: B) = x.substring(1)
}
val parent: Hello[Any] = child
parent.test(123) // child.test can't handle integer

但是我无法理解为什么以下代码无法编译:

trait Hello[+A] {
    def test[B<:A]
}

不同之处在于后者没有参数,我们无法将任何值传递给test方法。

为什么编译器仍认为它无效?

1 个答案:

答案 0 :(得分:4)

当您尝试在repl中执行此操作时,它会说:

scala> trait Hello[+A] {
     |     def test[B<:A](x: B)
     | }
<console>:8: error: covariant type A occurs in contravariant position in type  <: A of type B
           def test[B<:A](x: B)
                    ^

正确。想象一下,如果这是可能的,你可以:

val x:Hello[Dog] = new Hello[Dog]{..}
val y:Hello[Animal] = x
y.test(Cat)//Oops

关于参数,是什么让你认为它没有任何参数使它安全。您可以使用say implicitly获取变量并执行危险的东西,编译器不会阻止您。例如:

def test[B<:A]:B = this