模式匹配Seq与范围

时间:2015-03-11 14:24:52

标签: scala pattern-matching

考虑一段代码:

def foo(xs: Seq[Int]) = xs match {
  case Nil => "empty list"
  case head :: Nil => "one element list"
  case head :: tail => s"head is $head and tail is $tail"
}

val x1 = Seq(1,2,3)
println(foo(x1))

val x2 = Seq()
println(foo(x2))

val x3 = Seq(1)
println(foo(x3))

val problem = 1 to 10
println(foo(problem))

当我们尝试匹配foo(problem)中的范围时,会出现问题。

scala.MatchError: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) (of class scala.collection.immutable.Range$Inclusive)

使用val problem = (1 to 10).toSeq将范围转换为Seq是没用的,因为toSeq方法只返回Range本身:

override def toSeq = this

可以使用解决方法:

val problem = (1 to 10).toList.toSeq

但这并不是我见过的最漂亮的东西。

将Range与[head:tail]模式匹配的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以使用+:运算符。它与::类似,除了仅用于List,它适用于任何Seq。

def foo(xs: Seq[Int]) = xs match {
  case Seq() => "empty list"
  case head +: Seq() => "one element list"
  case head +: tail => s"head is $head and tail is $tail"
}

或者更好的是,只需Seq提取器上的模式匹配:

def foo(xs: Seq[Int]) = xs match {
  case Seq() => "empty list"
  case Seq(head) => "one element list"
  case Seq(head, tail @ _*) => s"head is $head and tail is $tail"
}