【问题标题】:Pattern Matching `@` Symbol模式匹配`@`符号
【发布时间】:2014-01-11 23:39:44
【问题描述】:

鉴于此Person 案例类:

scala> case class Person(name: String, age: Int) {}
defined class Person

...和这个实例

scala> val b = Person("Kevin", 100)
b: Person = Person(Kevin,100)

是否有理由更喜欢这段代码(@

scala> b match {
     |    case p @ Person(_, age) => println("age")
     |    case _ => println("none")
     | }
age

...在下面?

scala> b match {
     |    case Person(_, age) => println("age")
     |    case _ => println("none")
     | }
age

也许我错过了@ 的含义/力量?

【问题讨论】:

    标签: scala pattern-matching


    【解决方案1】:

    关于上述答案的cmets。

    考虑这个案例类。

    case class Employee(name: String, id: Int, technology: String)
    

    在进行模式匹配时。

    case e @ Employee(_, _, "scala") => e.name // matching for employees with only scala technology ... it works
    
    case x: Employee => x.name // It also works
    
    case e: Employee(_, _, "scala") => e.name // matching for employees with only scala technology ... **wont't work**
    

    【讨论】:

    • 此方案不需要@ 构造。你可以做case Employee(name, _, "scala") => name
    • 虽然第一行并不是完全需要的(根据先前的commrnt),但我非常感谢您简化的对比使我能够掌握区别。这只是一个边缘案例,即使在 Scala 使用了 8 年之后,我也忘记了这个特定的东西是如何以及为什么起作用的。
    【解决方案2】:

    仅当您还想处理对象本身时才包含@。因此:

    that match{
      case p @ Person(_, age) if p != bill => age
      case Person(_, age) => age - 15
      case _ => println("Not a person")
    }
    

    否则,包含它没有任何意义。

    【讨论】:

    • 您使用分号来引用对象本身。我想知道为什么不重复使用分号to refer the object itself
    • 很高兴知道!在阅读这个答案之前,我会这样写:case p: Person if p != bill => p.age
    • @erdavila 这没有错。它甚至可能在某些圈子中更受欢迎。
    • @Val 我花了很多时间思考这个问题,直到最近才弄明白。这是因为冒号(不是分号)匹配类型,但并非所有提取器都这样做。如果您制作自定义提取器,并且它嵌套在任何类型的另一个提取器中,您可能希望引用自定义提取器匹配的对象,但自定义提取器可能不会是该对象类型的名称,所以冒号不合适。
    • 更多关于使用不同语法进行模式匹配意味着什么。检查:scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html 了解更多信息
    猜你喜欢
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多