如果我取消注释指示的行,则下面的代码无法编译。编译器抱怨:“需要稳定的标识符”。
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
,它会起作用,但是如果没有这样的黑客攻击,你就无法在这样的基本值上进行模式匹配。
我错过了什么吗?
答案 0 :(得分:47)
您无法在Stream.empty
上进行模式匹配,因为它是方法(在对象Stream
中)始终返回空流(但编译器没有#&# 39;不知道。)
您可以匹配val empty = Stream.empty
Stream.Empty
,而不是分配Object
:
scala> a match {
case Stream.Empty => println("done")
case h #:: tl => println(h)
}
答案 1 :(得分:6)
您不能在非常常的变量上进行“模式匹配”
Stream.empty
不是“稳定”标识符,因为它代表了一些方法:
/** The empty stream */
override def empty[A]: Stream[A] = Empty
可能随时返回任何值。
编译器不知道其返回值始终为Empty
,因此它会将其检测为潜在的更改变量。
太深了,无法检测到它。
但是,当您将方法的retult分配给val
(因为不可变时是一个稳定的标识符)时,您的代码就可以使用它来处理模式匹配。
您可能会阅读this,引发一个假设,解释为什么模式匹配需要一个稳定的标识符。