排序Set后的MatchError

时间:2016-02-03 07:18:44

标签: scala pattern-matching

此代码编译良好,但在运行时失败:

    val values = Set("a").toSeq.sorted
    values match {
      case Nil => println("empty")
      case h::t => println(s"h = $h")
    }

显示错误消息:

  

scala.MatchError:ArrayBuffer(a)(类scala.collection.mutable.ArrayBuffer)

据我所知,在这个过程的某个地方创建了ArrayBuffer,我无法像这样进行模式匹配。但是,为什么编译器不能告诉我这不起作用?

2 个答案:

答案 0 :(得分:1)

您正在匹配开放(可扩展)数据类型Scala的Seq。它可能是List,因此Scala不会对您的列表模式抱怨。另一方面,无法检查详尽无遗,因为它实际上可能是任何实现Seq的类(我们甚至可能不会静态地知道),所以Scala只相信你。

您可以使用通用Seq模式:

values match {
  case Seq() => println("empty")
  case h +: t => println(s"h = $h")
}

或者只是转换为List并使用相同的模式(但List s不是非常有效的数据结构,所以第一个选项可能更好。)

val values = Set("a").toList.sorted
values match {
  case Nil => println("empty")
  case h::t => println(s"h = $h")
}

答案 1 :(得分:0)

从模式匹配中获取错误有时会很棘手,但在这种情况下:

scala> :type values
Seq[String]

scala> Seq(1,2,3) match { case h::t => "ok" }
res1: String = ok

没有足够的类型信息说它无法正常工作,并且它不会让你烦恼。