Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Examples for binding patterns to variables #3071

Merged
merged 2 commits into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions _overviews/scala3-book/control-structures.md
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,53 @@ speak(Person("Bam Bam")) // "Bam Bam says, Bam bam!"
{% endtab %}
{% endtabs %}

#### Binding matched patterns to variables

You can bind the matched pattern to a variable to use type-specific behavior.

{% tabs pattern-binding class=tabs-scala-version %}
{% tab 'Scala 2' for=pattern-binding %}
```scala
trait Animal {
val name: String
}
case class Cat(name: String) extends Animal {
def meow: String = "Meow"
}
case class Dog(name: String) extends Animal {
def bark: String = "Bark"
}

def speak(animal: Animal) = animal match {
case c @ Cat(name) if name == "Felix" => println(s"$name says, ${c.meow}!")
case d @ Dog(name) if name == "Rex" => println(s"$name says, ${d.bark}!")
case _ => println("I don't know you!")
}

speak(Cat("Felix")) // "Felix says, Meow!"
speak(Dog("Rex")) // "Rex says, Bark!"
```
{% endtab %}
{% tab 'Scala 3' for=pattern-binding %}
```scala
trait Animal:
val name: String
case class Cat(name: String) extends Animal:
def meow: String = "Meow"
case class Dog(name: String) extends Animal:
def bark: String = "Bark"

def speak(animal: Animal) = animal match
case c @ Cat(name) if name == "Felix" => println(s"$name says, ${c.meow}!")
case d @ Dog(name) if name == "Rex" => println(s"$name says, ${d.bark}!")
case _ => println("I don't know you!")

speak(Cat("Felix")) // "Felix says, Meow!"
speak(Dog("Rex")) // "Rex says, Bark!"
```
{% endtab %}
{% endtabs %}

### Using a `match` expression as the body of a method

Because `match` expressions return a value, they can be used as the body of a method.
Expand Down
21 changes: 21 additions & 0 deletions _tour/pattern-matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,27 @@ def goIdle(device: Device): String = device match

`def goIdle` has a different behavior depending on the type of `Device`. This is useful when the case needs to call a method on the pattern. It is a convention to use the first letter of the type as the case identifier (`p` and `c` in this case).

## Binding matched patterns to variables
You can use variable binding to get type-dependent behavior while simultaneously extracting fields from the matched pattern.

{% tabs pattern-matching-variable-binding class=tabs-scala-version %}
{% tab 'Scala 2' for=pattern-matching-variable-binding %}
```scala mdoc
def goIdleWithModel(device: Device): String = device match {
case p @ Phone(model) => s"$model: ${p.screenOff}"
case c @ Computer(model) => s"$model: ${c.screenSaverOn}"
}
```
{% endtab %}
{% tab 'Scala 3' for=pattern-matching-variable-binding %}
```scala
def goIdleWithModel(device: Device): String = device match
case p @ Phone(model) => s"$model: ${p.screenOff}"
case c @ Computer(model) => s"$model: ${c.screenSaverOn}"
```
{% endtab %}
{% endtabs %}

## Sealed types

You may have noticed that in the examples above the base types are qualified
Expand Down