2012-05-28 23 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

谢谢,这是我想到的更好的方式。 –