我可以理解为什么以下代码无法编译:
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
方法。
为什么编译器仍认为它无效?
答案 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