2

我有一张这样的地图:

val mealIdsMap: Map[String, String]    =
Map (
      "breakfast"     ->    "omelet",
      "lunch"         ->    "steak",
      "dinner"        ->    "salad"
)

然后我尝试在这样的匹配语句中使用它:

"omelet" match 
{ 
  case mealIdsMap("breakfast") => "Thank God"
}

我得到这个错误:

error: value mealIdsMap is not a case class constructor,
nor does it have an unapply/unapplySeq method
              case mealIdsMap("breakfast") => "Thank God"

任何人都知道如何在匹配/案例声明中使用这样的地图?

非常感谢你的帮助。

4

2 回答 2

7

您应该从教程中阅读模式匹配的目的是什么,可能来自这个(谷歌上的第一个非平凡示例)。

您已经反转了测试:

mealIdsMap("breakfast") match {
  case "omelet" => "Thank God"
  case _ => "Don't forget a default"
}

如果您不确定密钥是否存在(即使您是,如果您想编写惯用的 scala,您应该更喜欢:

mealIdsMap.get("breakfast") match {
  case Some("omelet") => "Thank God"
  case _ => "Don't forget a default"
}

Whereget返回一个选项,避免您尝试捕获代码或让它静默中断。

于 2012-05-03T14:38:16.980 回答
2

尽管如此,尝试实现这种行为仍然很有趣。看看这个例子:

  case class InvMatcher (m:Map[String, String]){
 def unapply(v:String):Option[String] = {
   return m collectFirst {case (k, `v`) => k}
 }

}

此类可帮助您逆向匹配地图。用法:

val ma = InvMatcher (Map (
  "breakfast"     ->    "omelet",
  "lunch"         ->    "steak",
  "dinner"        ->    "salad"
));

"steak" match {
  case ma(s) => s match {
    case "breakfast" => print("Thank God")
    case "lunch" => print("whatever")

    case _ => print("dont forget default")
  }
  case _ => print("dont forget default")
}

这几乎是您想要的,尽管您需要第二个匹配语句(这里不需要默认情况......)

于 2012-05-03T15:01:48.997 回答