scala编译器似乎为具有多个下限的语句提供了错误的类型错误。
使用方法Foo
为类g
使用A
和B
的下限
class Foo[A, B](a: A, b: B) {
def g[T, A1 >: A <: T, B1 >: B <: T] = List[T](a: A1, b: B1)
}
来自https://stackoverflow.com/a/6124549,以及类X
,Y <: X
和Z <: X
,
abstract class X {def a: String}
object Y extends X {def a = "this is Y"}
object Z extends X {def a = "this is Z"}
以下代码可以正常工作:
Y.a
new Foo(Y,Z).g
new Foo(Y,Z).g.head // instance of Y, type X
new Foo(Y,Z).g.head.isInstanceOf[X] // true
new Foo(Y,Z).g.head.asInstanceOf[X].a
new Foo(Y,Z).g[X,Y.type,Z.type].head.a
new Foo(Y,Z).g[X,X,X].head.a
{val y = new Foo(Y,Z).g.head; y}.a
令人惊讶的是,
new Foo(Y,Z).g.head.a
不是不是! (在Scala 2.12.7、2.12.8、2.13.0-M5中进行了测试,但在Dotty中确实可以正常工作)
它产生error: value a is not a member of type parameter T
。
这是编译器中的错误还是有特定原因,为什么我不能在a
上调用new Foo(Y,Z).g.head
?
y
的类型为X
,因此编译器 显然可以发现new Foo(Y,Z).g.head
的类型为X
,而我没有得到,为什么将其分配给新值并调用该方法有助于类型检查器。另外,我认为,显式强制转换为X
并不会改变任何东西,但是确实可以。