【问题标题】:Scala pattern matching on Map with arrow symbol带有箭头符号的地图上的Scala模式匹配
【发布时间】:2015-05-23 18:54:14
【问题描述】:
  1. List("a"->1, "b"->2) match { case List( k->v ,_*) => println(k) }
    错误:未找到:值 ->
  2. List("a"->1, "b"->2) match { case List( (k,v) ,_*) => println(k) }
    成功

  3. Map("a"->1, "b"->2) match { case Map( (k,v) ,_*) => println(k) }
    错误:value Map 不是 case 类,也没有 unapply/unapplySeq 成员

你能解释一下为什么左边使用箭头->成功吗?而在右手边,-> 失败了。
如果我把它改成真正的类型Tuple(k,v),那么它就成功了。
但是,如果使用 Map 会再次失败。 我无法想象 Scala 没有为 Map 实现 unapply?!


编辑: 我认为:: 可以用于模式匹配; -> 也可以。
好的,现在-> 是一个方法,所以不能匹配。 Scala 不直观。

【问题讨论】:

  • 您觉得不适合在地图上做什么?对于列表,有一个排序,所以很清楚匹配什么。对于地图,没有。

标签: scala pattern-matching


【解决方案1】:

-> 语法只是创建元组的简写。所以'a' -> 1 实际上返回了(Char, Int) 类型的东西。由于它不是一种类型,因此您无法匹配该语法。而是匹配元组。

对于地图,我不确定是否有一个提取器。你一般需要和unapplySeq方法,定义为返回一个序列。语法 _* 意味着传递一系列参数,而 map 根据定义是一种无序结构。您始终可以使用toSeq 来获取元组序列。

【讨论】:

  • 那么你的意思是,为了让-> 在模式匹配中工作,我需要实现一个带有 unapply 的-> 类?
  • 是的,我很久以前在我的 util 包中这样做了:type ->[A, B] = (A, B); object -> { def unapply[A, B](t: (A, B)) = Some(t) }
【解决方案2】:

您的代码版本 1. 适用于 2.13。

似乎->unapply 是在2.13.0 中添加的,即在PR Add -> alias for Tuple2 to Predef 中。 -> 符号是 Tuple2 案例类伴随对象的值别名,请参阅 Predef source

【讨论】:

  • 来自Predef sourceval -> = Tuple2。作为Tuple2 is a case class,这意味着它有一个自动生成的(和未记录的)伴侣object 和预期的unapply() 方法。因此-> 是对所述对象的引用(读取别名)。
猜你喜欢
  • 2015-10-07
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 2020-12-28
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多