2012-05-28 48 views
1

試圖修復客戶端API,但運行到一個問題就在這裏:包含選項的列表中的Scala模式匹配不接收類型?

case Some(List(Some(msgType:String), Some(channel:String), Some(data:String))) => 
     List(Some(msgType:String), Some(channel:String), Some(data:String)).foreach { 
      msgType match { 
       case "message" | "pmessage" => 
       fn(M(channel, data)) 
       case x => throw new RuntimeException("unhandled message: " + x) 
      } 
     } 

當我去編譯代碼,我得到的錯誤type mismatch; found : Any required: Some[String] => ?fn(M(channel, data))

如何正確結構匹配,因此收到類型?

回答

3

我們把這個了一下:

case Some(List(Some(msgType:String), Some(channel:String), Some(data:String))) => 
    List(Some(msgType:String), Some(channel:String), Some(data:String)).foreach { 

所以,在這一點上,你必須提供一個函數從Option[String]的東西。這是至關重要的一點:您需要將參數傳遞給foreach。讓我們繼續:

 msgType match { 

您可能正在努力的印象是這是一個功能 - 事實並非如此。也許你明白,但爲了以防萬一,讓我解釋一下這一點。一個函數具有參數,返回別的東西:它可以通過多種方式來聲明:

x => f(x) // anonymous function 
{ case x => f(x) } // pattern-matching anonymous function 
f _ // eta expansion of method f 
f(_) // partial function application 
_ + 1 // anonymous function with placeholder syntax 

注意msgType match {是以上皆非。

現在,msgType這裏指的是在第一種情況下匹配的內容。對於每次調用foreach(它將迭代器通過msgType,channeldata,因此,調用傳遞的函數三次),它將完全相同。

  case "message" | "pmessage" => 
      fn(M(channel, data)) 

現在我們到了問題的關鍵點。 fn(M(channel,data))是將傳遞給foreach的函數,因此fn的返回類型必須是String => ???。由於您沒有提供有關fnM的任何信息,因此我們無法評估可能存在的問題。

但是,也許你不打算讓fn返回一個函數,並搞砸了foreach。再一次,你沒有解釋你想完成什麼,所以我不能解釋如何完成它。

  case x => throw new RuntimeException("unhandled message: " + x) 
     } 
    } 
+0

更詳細,當然可以解釋我出錯的地方。你是對的,我沒有正確寫出這個foreach。我很抱歉沒有完全解釋我的預期結果。本質上,其目的是遍歷每條消息並創建一個fn(M()),它們是範圍內定義的類。他們回答了Akka演員的回調:) – crockpotveggies

0

我會做:

myList match { 
    case Some(xs @ List(Some(msgType:String), Some(channel:String), Some(data:String))) => 
    xs.foreach {...} 
    case _ => {...} 
} 

我希望它能幫助,哪怕一個更清潔的方式確實存在。

+0

上述唯一的問題是傳入模式並不總是列表。我同意,它看起來像它的作品,但有時它也是一個序列,所以我並不總是匹配一個列表。我確實得到了它的工作,結果證明我正在重寫不當的foreach。我將在一秒內發佈一個答案... – crockpotveggies

+0

您可以鍵入'Some(xs @ List(...))=> xs'來代替'Some(List(...))=> list.get' – sschaef

+0

謝謝,這是我想到的更好的方式。 –