Reputation: 27435
I'm new to Scala and was a little bit wondering of how pattern matching works. Imagine I have the following:
case class Cls(i: Int)
case b @ Cls(i) => //Ok
case e : Cls => //Ok
case f @ Cls => //Ok
case s: Cls(i) => //compile error
case str: String => //ok
I do not quite understand where to use @
and where to use :
. Is there some strictly defined rule?
Upvotes: 3
Views: 913
Reputation: 107
@ is called as binding operator, in pattern matching we use for name binding, it Basically stores the instance with the matched pattern, so that you can use the instance letter in the following expressions.
example
case class Person(name: String, id: Int)
val p1 = new Person("xxxx", 10)
val result = p1 match {
case x1 @ Person(n,i) => s"for object $x1 name is ${x1.person} and id ${i}"
case _ => "Wrong Object type"
}
println(result)
Output:- for object Person(xxxx, 10) name is xxxx and id 10
Note here we stored p1 object reference in x1 variable thus we can extract name and id in two ways 1st way - m x1.name or x1.id
2nd way - $n or $i
Upvotes: 1
Reputation: 149598
Use @
when you want to bind the entire matched type to a value, but also want to bind individual elements inside the type. This means that:
case b @ Cls(i) =>
Will assign b
to the reference of Cls
, such that you can access the i
value via b.i
. It will also bind i
to the first argument of the constructor pattern, which is of type Int
. This is useful when you need to evaluate individual values of the type but also need the entire reference to the class, i.e:
case b @ Cls(i) => if (i > 10) b else b.copy(i = 10)
If you only want to bind the entire reference of Cls
to a fresh value, use :
case e: Cls =>
This binds the reference to Cls
to e
.
If we want to get a bit more formal, case f @ Cls
is called Pattern Binders:
A pattern binder
x @ p
consists of a pattern variablex
and a patternp
. The type of the variablex
is the static typeT
of the patternp
. This pattern matches any valuev
matched by the patternp
, provided the run-time type ofv
is also an instance ofT
, and it binds the variable name to that value.
And case c: Cls
is called Typed Patterns:
A typed pattern
x:T
consists of a pattern variablex
and a type patternT
. The type ofx
is the type patternT
, where each type variable and wildcard is replaced by a fresh, unknown type. This pattern matches any value matched by the type patternT
; it binds the variable name to that value
Upvotes: 7