2012-12-23 81 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 => ... 
}