模式匹配`@`符号

Posted

技术标签:

【中文标题】模式匹配`@`符号【英文标题】: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

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

【问题讨论】:

【参考方案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 了解更多信息

以上是关于模式匹配`@`符号的主要内容,如果未能解决你的问题,请参考以下文章

如何编写正则表达式模式以匹配字符串结尾或字符串开头的货币符号

发布模式符号文件 .dll.mdb 中的 Fody 异常与程序集 .dll 不匹配

如何使用与PostgreSQL和Python的模式匹配与多个百分比(%)符号?

python使用rabbitMQ介绍五(话题模式)

Spark记录-Scala模式匹配

有趣的Scala模式匹配