Scala @运算符


Answers:


179

它使人们能够将匹配的模式绑定到变量。例如,考虑以下内容:

val o: Option[Int] = Some(2)

您可以轻松提取内容:

o match {
  case Some(x) => println(x)
  case None =>
}

但是,如果您不想 内容Some,但选择本身?可以这样实现:

o match {
  case x @ Some(_) => println(x)
  case None =>
}

请注意,它@可以在任何级别使用,而不仅限于匹配的最高级别。


5
我在文档中哪里可以找到答案?我觉得这里还有其他好东西。:)
吉姆·巴罗斯

1
@Jim Scala参考,8.1。具体来说,虽然我不知道第8.12节的“往常情况”来自何处,但第8.12节仅谈到正则表达式模式(_*)。但是,也许在更新版本的规范中已经阐明了这一点。
Daniel C. Sobral'3

16
我要补充一点,您可能不会@与with一起使用Some(_),而是希望与的内容匹配Some,但仍引用Some本身,例如case x @ Some(7) => println(x)。根据我的解释,它case x @ Some(_)只是的更详细的版本case x: Some
西奥

2
在“ Scala编程-第2版”的15.2节的“变量绑定”中也对此进行了介绍,并在26.3节(有关提取程序的章节)中再次使用了该变量。
肖恩(Shaun)

@Theo case x: Some不能独立工作。你必须使用case x: Some[_],这是不那么冗长
路易吉Plinge

74

@可用于将名称绑定到成功匹配的模式或子模式。模式可用于模式匹配,输入的左手侧<-以进行理解,以及用于销毁配置。

scala> val d@(c@Some(a), Some(b)) = (Some(1), Some(2))
d: (Some[Int], Some[Int]) = (Some(1),Some(2))
c: Some[Int] = Some(1)
a: Int = 1
b: Int = 2

scala> (Some(1), Some(2)) match { case d@(c@Some(a), Some(b)) => println(a, b, c, d) }
(1,2,Some(1),(Some(1),Some(2)))

scala> for (x@Some(y) <- Seq(None, Some(1))) println(x, y)
(Some(1),1)

scala> val List(x, xs @ _*) = List(1, 2, 3) 
x: Int = 1
xs: Seq[Int] = List(2, 3)

10

当模式匹配variable @ pattern结合可变由匹配的值模式,如果模式匹配。在这种情况下,这意味着值xSome(Nil)在该案例子句中。


9

允许您匹配模式的顶层。例:

case x @ "three" => assert(x.equals("three"))
case x @ Some("three") => assert(x.get.equals("three")))
case x @ List("one", "two", "three") => for (element <- x) { println(element) }

6
不只是顶层。
Daniel C. Sobral'3

2

它将的值设置为x匹配的模式。x因此,在您的示例中,将为Some(Nil)(您可以通过调用println确定)


1
该死的iPhone无法渲染背景!
oxbow_lakes
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.