为什么空字符串与Seq.empty不匹配?

时间:2009-04-11 19:26:11

标签: scala pattern-matching sequence

编辑:这是一个很久以来在Scala 2.8及更高版本中修复的旧bug

在围绕问题Pattern matching a String as Seq[Char]的一些实验中,我遇到了另一种奇怪的匹配现象。请考虑以下将字符串视为字符序列的代码:

def %%&#(input: String) : String =  {
    val uha : Seq[Char] = input
    uha match {
        case Seq() => "Empty"
        case Seq(first @ _, 'o', 'o')  => "Bar"
        case _ => "Oh" 
    }
}

在空字符串""上调用输入正确地产生"Empty"

但是,如果我将第一个匹配子句重写为

case Seq.empty => "Empty"

""的匹配失败并改为匹配默认子句。

浏览Scala库源代码(在理想世界中你不应该这样做:-))我相信Seq()Seq.empty都会导致RandomAccessSeq.empty 。显然,这与上述现象不一致,因为只有Seq()匹配空字符串。

更新:经过一些进一步的实验,这个问题可以缩小到以下几个方面:

val list = List()
   >>> list2: List[Nothing] = List()
val emptySeq = Seq.empty
list == emptySeq
   >>> res1: Boolean = false

这基本上意味着空Seq不会自动等于Seq.empty。 因此,当匹配常数时(与使用starblue建议的提取器相反),这种不平等导致失败的匹配。 将空String解释为序列时也是如此。

2 个答案:

答案 0 :(得分:4)

这似乎是图书馆中的一个错误。你想提交这个错误还是我?

scala> Seq.empty  match {case Seq() => "yup"; case _ => "nope"}
res0: java.lang.String = yup

scala> Seq()  match {case Seq.empty => "yup"; case _ => "nope"}
res1: java.lang.String = yup

scala> ("" : Seq[Char]) match {case Seq() => "yup"; case _ => "nope"}    
res2: java.lang.String = yup

scala> ("" : Seq[Char]) match {case Seq.empty => "yup"; case _ => "nope"}
res3: java.lang.String = nope

答案 1 :(得分:0)

在匹配unapply或unapplySeq函数时,不会像你想象的那样应用。