对具有与返回类型匹配的类型的泛型值执行模式匹配

时间:2016-06-27 17:52:07

标签: scala generics pattern-matching

我有一个问题,在下面的例子中,如何编译函数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中是不可能的。

1 个答案:

答案 0 :(得分:0)

bar2中的情况比最初看起来更复杂。例如。想象一下String的子类叫String1。如果TString1key将匹配case k: String,但"hallo"的类型错误。没有这样的子类型,因为String恰好是最终的,但如果编译或不编译也会很奇怪,这取决于String的终结性。

bar1有效,因为这种特定模式(称为GADT:广义代数数据类型)具有一些特殊的编译器支持。这种支持并不完美:参见例如https://gist.github.com/pchiusano/1369239