2012-12-23 49 views
4

我写了一个名为提取物,定义函数如下:斯卡拉:toSeq VS SEQ(东西:_ *)

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 
} 

每当我的模式情况下无=>分支匹配,我得到一个

scala.MatchError: WrappedArray(T) (of class scala.collection.mutable.WrappedArray$ofRef) 
在另一方面

,如果我更换结果toSeqSEQ(结果:_ *)提取物功能,一切工作正常。

任何人都可以解释这种行为吗?

+0

从列表\ [(字符,字符)[奇怪的类型转换的可能重复\ ] to Object](http://stackoverflow.com/questions/13754800/strange-type-conversion-from-listchar-char-to-object) –

+2

总之,通过编写head :: Nil,指示模式匹配等待a ** List **,但不是所有的Seq都是列表(例如WrappedArray **不是**列表)。参见上面的链接。为了做到这一点,你可以用'.toList'替换'.toSeq'。 –

+0

@ om-nom-nom谢谢你的回答,但我已经找到了解决我的问题的方法(用** Seq(result:_ *)**取代**结果给Seq**),我只是想知道为什么会发生这种情况因为(据我所知),** :: **提取模式应该支持所有序列,即使它们不是列表... – fedragon

回答

0

现在,ULTIMATE MATCH

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

而且,再次我有一点怀疑 - 一切是这里的List

...

toList,或者您的Seq(someething: _*)变种会再次创建一个List

+0

你是不是指'Seq()'?这会匹配一个空的'Seq',但他仍然会在第二和第三种情况下出现问题。 –

+0

Umm我认为这个问题只针对'Nil' =) – idonnie

+1

我更喜欢'toList',因为它比可变参数有更明显的意图和更高的性能,尽管不是那么多。也许写出模式匹配就像'case Seq ()=> ... case Seq(head)=> ... case Seq(head,tail:_ *)=>'如果没有转换到列表完成? –

3

Nil::的提取,只有匹配List类型的实例。你通过了Seq,这是一个更普遍的特征,可能是也可能不是List

当您使用Seq(...)构造Seq时,默认情况下,Scala生成ListtoSeq也不能这样说,它通常将底层集合封装在最合适的接口中。例如,Iterator.toSeq产生Stream,而Array.toSeq产生WrappedArray

这就是为什么当您拨打toSeq时您的代码不起作用; String.split产生Array(这是来自原始Java String类的方法),并且map保持其类型。您可以添加一个案例来处理Seq的实例,或者让您的extract方法返回List

+1

这是有道理的......谢谢! – fedragon

2

对于一般Seq你改变了比赛如下:

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

斯卡拉2。10有Seq等同于那些List提取,所以只需更换NilSeq()::+:,它会工作:

extract(myInputString) match { 
    case Seq() => ... 
    case head +: Seq() => ... 
    case head +: tail => ... 
}