Operador Scala @

Respuestas:

179

Le permite a uno vincular un patrón coincidente a una variable. Considere lo siguiente, por ejemplo:

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

Puede extraer fácilmente el contenido:

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

Pero lo que si usted quiere no es el contenido de Some, pero la opción de sí misma? Eso se lograría con esto:

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

Tenga en cuenta que @se puede usar en cualquier nivel, no solo en el nivel superior de la coincidencia.

Daniel C. Sobral
fuente
55
¿En qué parte de la documentación encontraría esa respuesta? Tengo la sensación de que también hay otras cosas buenas enterradas allí. :)
Jim Barrows
1
@Jim Scala Referencia, 8.1. 8.12, específicamente, aunque no sé de dónde vino el "como siempre", y 8.12 solo habla del patrón de expresión regular ( _*). Pero tal vez esto se ha aclarado en una versión más nueva de la especificación.
Daniel C. Sobral
16
Agregaría que probablemente no usaría @con Some(_), sino más bien si desea hacer coincidir el contenido de la Some, pero aún se refiere a Some en sí, por ejemplo case x @ Some(7) => println(x). Según lo interpreto, case x @ Some(_)es solo una versión más detallada de case x: Some.
Theo
2
Esto también está cubierto en "Enlace variable" en la Sección 15.2 de "Programación en Scala - 2ª Edición" y se utiliza nuevamente en la sección 26.3 (el capítulo sobre extractores).
Shaun the Sheep
@Theo case x: Someno funciona por sí solo. Tienes que usar case x: Some[_], que no es menos detallado
Luigi Plinge
74

@se puede usar para vincular un nombre a un patrón o subpatrón que coincida correctamente Los patrones se pueden usar en la coincidencia de patrones, el lado izquierdo de la entrada <-para comprender y en tareas de desestructuración.

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)
retrónimo
fuente
10

Cuando la coincidencia de patrones variable @ patternvincula la variable al valor que coincide con el patrón si el patrón coincide. En este caso, eso significa que el valor de xestará Some(Nil)en esa cláusula de caso.

sepp2k
fuente
9

Le permite hacer coincidir el nivel superior de un patrón. Ejemplo:

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) }
Mitch Blevins
fuente
66
No solo de nivel superior.
Daniel C. Sobral
2

Establece el valor de xal patrón que coincide. Por xlo tanto , en su ejemplo, sería Some(Nil)(como podría determinar a partir de una llamada a println )

oxbow_lakes
fuente
1
¡Maldita sea la incapacidad de los iPhones para hacer un backtick!
oxbow_lakes