4

我写了一个名为extract的函数,定义如下:

def extract(params: String): Seq[String] = {
  val result = params.split(",") map (param => param.trim())
  result toSeq
}

然后我对提取结果执行模式匹配,如下所示:

extract(myInputString) match {
  case Nil => // do something
  case head :: Nil => // do something
  case head :: tail => // do something
}

每当我的模式匹配case Nil =>分支时,我都会得到一个

scala.MatchError: WrappedArray(T) (of class scala.collection.mutable.WrappedArray$ofRef)

另一方面,如果我在提取函数中将结果 toSeq替换为Seq(result:_*),则一切正常。

谁能解释一下这种行为?

4

3 回答 3

4

Nil并且::是仅匹配类型实例的提取器List。您正在传递 a Seq,这是一个更普遍的特征,可能是也可能不是 a List

当你构建一个SequsingSeq(...)时,ScalaList默认构建一个。不能这样说toSeq,它通常将底层集合封装在最合适的Seq接口中。例如,Iterator.toSeq产生 a Stream,而Array.toSeq产生 a WrappedArray

这就是为什么您的代码在您调用时不起作用的原因toSeqString.split产生一个Array(它是来自原始 JavaString类的方法),并map维护它的类型。您可以添加一个案例来处理实例Seq或让您的extract方法返回一个List.

于 2012-12-23T23:02:43.170 回答
2

对于 general Seqs,您按如下方式进行匹配:

extract(myInputString) match { 
  case Seq() => ...
  case Seq(head) => ...
  case Seq(head, tail @ _*) => ...
}

Scala 2.10 具有Seq与 on 等效的提取器List,因此只需替换为NilSeq()就可以了:::+:

extract(myInputString) match {
  case Seq() => ...
  case head +: Seq() => ...
  case head +: tail => ...
}
于 2012-12-24T09:36:12.707 回答
0

现在,终极比赛

extract("a, b") match { 
  case Seq() => "0"
  case Seq(a, b, _*) => "many"
  case Seq(a, _*) => "1"
}

而且,我再次有点怀疑 - 一切都在List这里。

...

toList,或者您的变体Seq(someething: _*)将再次创建,List

于 2012-12-23T22:57:40.243 回答