Scala 对集合排序后出现匹配错误
此代码编译良好,但在运行时失败:Scala 对集合排序后出现匹配错误,scala,pattern-matching,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类) 我知道在这个
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
,我无法像这样进行模式匹配。但是,为什么编译器不能告诉我这是行不通的呢?从模式匹配中获取错误有时会很棘手,但在这种情况下:
scala> :type values
Seq[String]
scala> Seq(1,2,3) match { case h::t => "ok" }
res1: String = ok
没有足够的类型信息来说明它无法工作,而且它的错误在于不打扰您。您正在匹配一个开放(可扩展)数据类型,Scala的
Seq
。它可能是一个列表
,因此Scala不会对您的列表模式感到不满。另一方面,无法检查穷尽性,因为它实际上可能是任何实现Seq
(我们甚至可能静态地不知道)的类,所以Scala在这一点上信任您
您可以使用通用Seq
模式:
values match {
case Seq() => println("empty")
case h +: t => println(s"h = $h")
}
或者只是转换成列表
并使用相同的模式(但是列表
不是非常有效的数据结构,所以使用第一个选项可能更好)
因为
::
只是一个函数(unapply
),编译器无法知道它将匹配什么和不匹配什么。
val values = Set("a").toList.sorted
values match {
case Nil => println("empty")
case h::t => println(s"h = $h")
}