我试图复制Joshua Suereth在2013年Devoxx的题为"如何在战壕中使用Scala"的演讲中提出的强大模式匹配示例.不幸的是,我无法实现他所描述的,我无法理解什么是错的.有人能给我一些暗示我缺少的东西吗?(我的Scala版本是2.10.3)
请参阅下面的自包含代码:
case class Person(name: String, residence: Seq[Residence]) case class Residence(city: String, country: String) object LivesIn { def unapply(p: Person): Option[Seq[String]] = Some( for(r <- p.residence) yield r.city ) } class StringSeqContains(value: String) { def unapply(in: Seq[String]): Boolean = in contains value } object PatternPower extends App { val people = Seq(Person("Emre", Seq(Residence("Antwerp", "BE"))), Person("Ergin", Seq(Residence("Istanbul", "TR")))) val Istanbul = new StringSeqContains("Istanbul") // #1 does not work as expected, WHY? println( people collect { case person @ LivesIn(Istanbul) => person } ) // #2 works as expected println( people collect { case person @ LivesIn(cities) if cities.contains("Istanbul") => person } ) // #3 works as expected println( people collect { case person @ Person(_, res) if res.contains(Residence("Istanbul", "TR")) => person } ) }
当我编译并运行它时,我得到:
List() List(Person(Ergin,List(Residence(Istanbul,TR)))) List(Person(Ergin,List(Residence(Istanbul,TR))))
如源代码所示,我无法理解为什么第一个模式不会产生与其余两个模式匹配相同的结果.有什么想法吗?
你的LivesIn提取器需要一个参数的Seq.
以下变体符合您的期望:
println( people collect { case person @ LivesIn(List("Istanbul")) => person } )