如何在地图上进行模式匹配?

时间:2016-02-12 05:48:14

标签: scala

val map @ Map(p1, p2) = Map("key1" -> "value1", "key2" -> "value2")

但是下面给出了编译器错误:

<header-main></header-main>
<router-outlet></router-outlet>
<footer>...</footer>

value Map不是case类,也没有unapply / unapplySeq成员

避免错误的正确语法是什么?

1 个答案:

答案 0 :(得分:2)

问题显然是Map没有unapplySeq方法。拥有它可能没有多大意义,因为你不知道你将获得你的元素的顺序。

无论如何,我能得到的最接近的是:

scala> object MapOops {
     |   def apply[K,V](ps: (K,V)*): Map[K,V] =
     |     ps.toMap
     |
     |   def unapplySeq[K,V](m: Map[K,V]): Option[Seq[(K,V)]] =
     |     if(m.isEmpty) None else Some(m.toSeq)
     | }
defined object MapOops

scala> val map@MapOops(p1, p2) = MapOops(1 -> "one", 2 -> "two")
map: Map[Int,String] = Map(1 -> one, 2 -> two)
p1: (Int, String) = (1,one)
p2: (Int, String) = (2,two)

或者更短:

scala> val map@MapOops(p1, p2) = Map(1 -> "one", 2 -> "two")
map: scala.collection.immutable.Map[Int,String] = Map(1 -> one, 2 -> two)
p1: (Int, String) = (1,one)
p2: (Int, String) = (2,two)

皮条客Map与此类似的事情没有意义:

implicit class MapOops[K,V](val m: Map[K,V]) extends AnyVal

因为在模式匹配中使用Map时,由于MapOops类型未被请求/暗示,因此不会发生隐式转换。

例如:case Map(...)val Map(...)需要输入Map,而不是MapOops,因此不会进行隐式转换,也不会找到unapplySeq方法。如果您明确使用MapOops,则不需要隐式转换。

如果您经常使用这种模式,那么您可能会发现这个帮助程序类很有用,否则更合理的解决方案是在@jwvh的答案中进行额外的转换。