【问题标题】:Why does the empty string not match as Seq.empty?为什么空字符串与 Seq.empty 不匹配?
【发布时间】:2015-04-15 23:36:33
【问题描述】:

编辑:这是很久以前在 Scala 2.8 及更高版本中修复的老错误

在围绕问题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 解释为序列时也是如此。

【问题讨论】:

  • 显然,这将在 Scala 2.8 中解决。敬请期待。
  • 好案例,但现在已经过期,因为错误已修复(可能已经在几年前)。什么是 Stackoverflow 政策将这些置于静止状态,使其不会出现在搜索中?
  • 您能否以某种方式标记这仅适用于 Scala meta.stackoverflow.com/questions/252520/…

标签: scala pattern-matching sequence


【解决方案1】:

这似乎是库中的错误。你想提交错误还是我应该提交?

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

【讨论】:

  • 所以 bug 确实是 Seq[A] 的许多子类型,例如 List 和 RichString 在构造时不等于 Seq.empty(使用 List() 和 ("": Seq[ Char])),而其他诸如 RandomAccessSeq 是。这可能是出于某种原因故意的吗?
【解决方案2】:

在匹配中使用了 unapply 或 unapplySeq 函数,而不是像您所相信的那样应用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    相关资源
    最近更新 更多