为什么这种模式匹配在Scala中没有像预期的那样工作?

 心上锁退 发布于 2023-02-06 20:24

我试图复制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))))

如源代码所示,我无法理解为什么第一个模式不会产生与其余两个模式匹配相同的结果.有什么想法吗?

1 个回答
  • 你的LivesIn提取器需要一个参数的Seq.

    以下变体符合您的期望:

    println(
      people collect {
        case person @ LivesIn(List("Istanbul")) => person
      }
    )
    

    2023-02-06 20:27 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有