我有一个问题,在下面的例子中,如何编译函数bar1但是bar2没有。
trait Key[T] {
}
trait KeyString extends Key[String]
class Foo {
def bar1[T]( key: Key[T] ): T = key match {
case k: KeyString => "hallo"
}
/*def bar2[T](key: T): T = key match {
case k: String => "hallo"
}*/
}
有人可以解释一下,为什么在bar1中编译器可以弄清楚," hallo"是类型T,在bar2中是不可能的。
答案 0 :(得分:0)
bar2
中的情况比最初看起来更复杂。例如。想象一下String
的子类叫String1
。如果T
为String1
,key
将匹配case k: String
,但"hallo"
的类型错误。没有这样的子类型,因为String
恰好是最终的,但如果编译或不编译也会很奇怪,这取决于String
的终结性。
bar1
有效,因为这种特定模式(称为GADT:广义代数数据类型)具有一些特殊的编译器支持。这种支持并不完美:参见例如https://gist.github.com/pchiusano/1369239