3

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?

1

2 Answers 2

7

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 variable x and a pattern p. The type of the variable x is the static type T of the pattern p. This pattern matches any value v matched by the pattern p, provided the run-time type of v is also an instance of T, 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 variable x and a type pattern T. The type of x is the type pattern T, where each type variable and wildcard is replaced by a fresh, unknown type. This pattern matches any value matched by the type pattern T; it binds the variable name to that value

Sign up to request clarification or add additional context in comments.

1 Comment

If you are new to Scala, maybe have a look at Extractors. Via the apply and unapply methods you can define how the Pattern-Matching behaves.
1

@ 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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.