【问题标题】:Perform pattern match on a generic value with type matching the return type对类型与返回类型匹配的泛型值执行模式匹配
【发布时间】:2016-10-29 20:05:35
【问题描述】:

在以下示例中,我无法理解函数 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 中这是不可能的。

【问题讨论】:

    标签: scala generics pattern-matching


    【解决方案1】:

    bar2 的情况比最初看起来要复杂。例如。假设有一个String 的子类,称为String1。那么如果TString1key 将匹配case k: String,但"hallo" 将有错误的类型。没有这样的子类型,因为 String 恰好是 final 的,但是这个编译与否也很奇怪,这取决于 String 的 finality。

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

    【讨论】:

    • 感谢您的出色回答。只有一件事我不明白:如果它是基于 String 的最终确定性(或者通常是结果类型)编译的,为什么会很奇怪。如果结果类型是 final 并且等于匹配的类型,那么推断 T 等于该类型是正确的,对吧?
    • 好的,我自己找到了答案:T 仍然可以是实例的单例类型,最终性不排除。见:issues.scala-lang.org/browse/SI-127
    猜你喜欢
    • 2011-10-25
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 2015-04-09
    相关资源
    最近更新 更多