【问题标题】:Why can't I pattern match on Stream.empty in Scala?为什么我不能在 Scala 中的 Stream.empty 上进行模式匹配?
【发布时间】:2015-02-15 20:29:14
【问题描述】:

如果我取消注释指示的行,下面的代码将无法编译。编译器抱怨:“需要稳定的标识符”。

val Empty = Stream.empty    
val a = Stream.range(0, 5)
a match {
  // case Stream.empty => println("nope") <-- does not work
  case Empty => println("compiles") <-- works
  case _ => println("ok")
}

如果我首先将 Stream.empty 分配给值 Empty,它会起作用,但是如果没有这样的 hack,你就无法在这样一个基本值上进行模式匹配,这感觉很奇怪。

我错过了什么吗?

【问题讨论】:

    标签: scala pattern-matching


    【解决方案1】:

    您不能在Stream.empty 上进行模式匹配,因为它是一个始终返回空流(但编译器不知道)的方法(在对象Stream 中)。

    您可以匹配Stream.Empty,而不是分配val empty = Stream.empty,这是一个Object

    scala> a match {
               case Stream.Empty => println("done")
               case h #:: tl => println(h)
           }
    

    【讨论】:

    • 确认它至少适用于 Scala 2.12。从 2.13 开始,情况可能会有所不同。
    【解决方案2】:

    您不能对非常量变量进行“模式匹配”。
    Stream.empty 不是“稳定”标识符,因为它代表某种方法:

    /** The empty stream */
      override def empty[A]: Stream[A] = Empty
    

    可能随时返回任何值。
    编译器不知道它的返回值始终是Empty,因此它会将其检测为潜在的变化变量
    太深了,检测不到。

    但是,当您将方法的 retult 分配给 val(因为它是不可变的稳定标识符)时,您的代码可以使用它来处理模式匹配。

    您可能会阅读this,它引发了一个假设,解释了为什么模式匹配需要一个稳定的标识符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      相关资源
      最近更新 更多