为什么我不能在Scala中对Stream.empty进行模式匹配?

Bas*_*ato 28 scala pattern-matching

如果我取消注释指示的行,则下面的代码不会编译.编译器抱怨:"需要稳定的标识符".

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")
}
Run Code Online (Sandbox Code Playgroud)

如果我首先赋值Stream.emptyEmpty它,它会起作用,但是如果没有这样的黑客,你就无法在这样的基本值上进行模式匹配.

我错过了什么吗?

Mar*_*rth 48

你不能模式匹配,Stream.empty因为它是一个总是返回空流的方法(在对象中Stream)(但编译器不知道).

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

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


Mik*_*378 6

您不能对不是常量变量进行 "模式匹配" .
Stream.empty不是一个"稳定"的标识符,因为它代表了一些方法:

/** The empty stream */
  override def empty[A]: Stream[A] = Empty
Run Code Online (Sandbox Code Playgroud)

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

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

您可能会读到这一点,引发一个假设,解释为什么模式匹配需要一个稳定的标识符.