
- Scala - Home
- Scala - Overview
- Scala - Features
- Scala - Environment Setup
- Scala - Build Tool (SBT)
- Scala - REPL
- Scala - Dot & Dotty
- Scala - Basic Syntax
- Scala - Hello World Program
- Scala - Identifiers
- Scala - Keywords
- Scala - Comments
- Scala - Code Blocks
- Scala - Semicolon
- Scala - Constructs
- Scala - Expressions
- Scala - Input and Output
- Scala - Optional Braces
- Scala - Underscore (_)
- Data Types and Variables
- Scala - Data Types
- Scala - Type Bounds
- Scala - Context Bound
- Scala - Variances
- Scala - Type Hierarchy
- Scala - Variables
- Scala - Variable Scopes
- Scala - Literals
- Scala - Numeric Types
- Scala - Boolean Types
- Scala - Char Type
- Scala - Unit Types
- Scala - Strings
- Scala - Arrays
- Scala - Null Type
- Scala - Nothing
- Scala - Any Type
- Scala - AnyRef Type
- Scala - Unified Types
- Scala - Dates and Times
- Scala - Ranges
- Scala - Multidimensional Arrays
- Scala - WrappedArray
- Scala - StringBuilder
- Scala - String Interpolation
- Scala - StringContext
- Scala - Type Casting
- Scala var vs val
- Scala Operators
- Scala - Operators
- Scala - Rules for Operators
- Scala - Arithmetic Operators
- Scala - Relational Operators
- Scala - Logical Operators
- Scala - Bitwise Operators
- Scala - Assignment Operators
- Scala - Operators Precedence
- Scala - Symbolic Operators
- Scala - Range Operator
- Scala - String Concatenation Operator
- Scala Conditional Statements
- Scala - IF ELSE
- Scala - IF-ELSE-IF-ELSE Statement
- Scala - Nested IF-ELSE Statement
- Scala Loop Statements
- Scala - Loop Statements
- Scala - while Loop
- Scala - do-while Loop
- Scala - Nested Loops
- Scala - for Loop
- Scala - break Statement
- Scala - yield Keyword
- Scala Classes & Objects
- Scala - Classes & Objects
- Scala - Constructors
- Scala - Auxiliary Constructor
- Scala - Primary Constructor
- Scala - This Keyword
- Scala - Nested Classes
- Scala - Getters and Setters
- Scala - Object Private Fields
- Scala - Singleton Object
- Scala - Companion Objects
- Scala - Creating Executable Programs
- Scala - Stateful Object
- Scala - Enumerations
- Scala - Polymorphism
- Scala - Access Modifiers
- Scala - Apply Method
- Scala - Update Methods
- Scala - UnapplySeq Method
- Scala - Inheritance
- Scala - Extending a Class
- Scala - Method Overloading
- Scala - Method Overriding
- Scala - Generic Classes
- Scala - Generic Functions
- Scala - Superclass Construction
- Scala Methods & Functions
- Scala - Methods
- Scala - Functions
- Scala - Methods vs Functions
- Scala - Main Methods
- Scala - Functions Call-by-Name
- Scala - Functions with Named Arguments
- Scala - Function with Variable Arguments
- Scala - Recursion Functions
- Scala - Default Parameter Values
- Scala - Functions without Parameters
- Scala - Implicit Parameters
- Scala - Higher-Order Functions
- Scala - Nested Functions
- Scala - Extension Methods
- Scala - Anonymous Functions
- Partially Applied Functions
- Scala - Lazy Val
- Scala - Pure Function
- Scala - Currying Functions
- Scala - Control Abstractions
- Scala - Corecursion
- Scala - Unfold
- Scala - Tail Recursion
- Scala - Infinite Sequences
- Scala - Dynamic Invocation
- Scala - Lambda Expressions
- Scala - Polymorphic Functions
- Scala Collections
- Scala - Collections
- Mutable and Immutable Collections
- Scala - Lists
- Scala - Sets
- Scala - Maps
- Scala - TreeMap
- Scala - SortedMap
- Scala - Tuples
- Scala - Iterators
- Scala - Options
- Scala - NumericRange
- Scala - Infinite Streams
- Scala - Parallel Collections
- Scala Advanced Types
- Scala - Union Types
- Scala - Intersection Types
- Scala - Type Aliases
- Scala - Structural Types
- Scala - Match Expression
- Scala - Singleton Type Operator
- Scala - Abstract Types
- Scala - Dependent Types
- Scala - Abstract Type Bounds
- Scala - Higher-Kinded Types
- Scala - Opaque Type Alias
- Scala - Path-Dependent Types
- Scala - Type Lambdas
- Scala - Type Inference
- Scala - Algebraic Data Types
- Scala Pattern Matching
- Scala - Pattern Matching
- Scala - Guards
- Scala - Variables in Patterns
- Scala - Type Patterns
- Scala - The Matchable Trait
- Scala - Matching Arrays
- Scala - Matching Lists
- Scala - Matching Tuples
- Scala - Exception Handling
- Scala - Extractors
- Scala - Pattern Bindings
- Scala - Regular Expressions
- Scala - Case Classes
- Scala - Partial Functions
- Scala - Packaging and Imports
- Scala - Implicit Imports
- Scala - Export Clauses
- Scala - Nested Packages
- Scala - Chained Packages
- Scala - Package Objects
- Scala Files I/O
- Scala - Files I/O
- Scala - Writing Files
- Scala - Listing Files
- Scala - Deleting Directories
- Scala - Check File Exists
- Scala Advanced Concepts
- Scala - Closures
- Scala - Futures
- Scala - Promises
- Scala - Traits
- Scala - Trait Mixins
- Scala - Layered Traits
- Scala - Trait Linearization
- Scala - Sealed Traits
- Scala - Transparent Traits
- Scala - Process Management
- Scala - Scaladoc
- Scala - Literal Type Arithmetic
- Scala - Inline keyword
- Scala - Def, Var & Val
- Scala - Dropped Features
- Scala Unit Testing
- Scala - Unit Testing
- Scala - uTest
- Scala - MUnit
- Scala - ScalaTest Runner
- Scala - ScalaMock
- Scala - JUnit
- Scala - Mocking
- Scala - BDD Testing
Scala Guards in Pattern Matching and Case Statements
Guards are constructs that we can use to increase the power of pattern matching. Using guards, we can perform simple tests and comparisons on the variables in a pattern.
The general syntax of the guard statement is as follows:
pattern guard => result
Where,
- pattern: The pattern to match.
- guard: A boolean expression that must evaluate to true for the pattern to match.
- result: The expression to evaluate if the pattern matches and the guard condition is satisfied.
The if statement must be used when a guard condition is specified.
Try this example of how guards can be used -
Example
object Demo { def main(args: Array[String]): Unit = { println(matchTest(11)) println(matchTest(5)) println(matchTest("Scala")) } def matchTest(x: Any): String = x match { case i: Int if i > 10 => "greater than 10" case i: Int if i < 10 => "less than 10" case _ => "not an integer" } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
greater than 10 less than 10 not an integer
The following points need to be noted about the above example -
- The matchTest function is defined with guards. The first case has a guard condition to check if the integer is greater than 10. If true, it returns "greater than 10".
- The second case checks if the integer is less than 10. If true, it returns "less than 10".
- The third case catches all other values and returns "not an integer".
Guards for if Statements
Guards can also be used for if statements so that the series of statements executed is based on the guard condition. Try this following example to see how we can achieve this -
Example
object Demo { def main(args: Array[String]): Unit = { val N = 9 if (N > 10) { println("N is greater than 10") } else { println("N is less than 10") } } }
The following points need to be noted about the above example -
- The guard condition is used within the if If the guard condition evaluates to true, the statement "N is greater than 10" is displayed.
- If the guard condition evaluates to false, the statement "N is less than 10" is displayed.
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
N is less than 10
Guards for case Statements
Guards can also be used for case statements so that the series of statements executed is based on the guard condition. Try this following example to see how we can achieve this -
Example
object Demo { def main(args: Array[String]): Unit = { val A = 9 A match { case x if x > 10 => println("The value of A is greater than 10") case _ => println("The value of A is less than 10") } } }
The following points need to be noted about the above example -
- The guard condition is used along with the case If the guard condition evaluates to true, the statement "The value of A is greater than 10" is displayed.
- If the guard condition evaluates to anything else, the statement "The value of A is less than 10" is displayed.
Command
> scalac Demo.scala > scala Demo
Output
The value of A is less than 10
Multiple Guard Conditions
Multiple guard conditions can also be specified for a pattern. The general syntax of the guard statement with multiple guard conditions is as follows:
case pattern if condition1 && condition2 && ... => result
Where,
- pattern: The pattern to match.
- condition1, condition2, ...: These are the multiple guard conditions which are applied to the pattern.
- result: The expression to evaluate if the pattern matches and all guard conditions are satisfied.
Try this following example of how multiple guards can be used -
Example
object Demo { def main(args: Array[String]): Unit = { println(matchTest(11)) println(matchTest(5)) println(matchTest("Scala")) } def matchTest(x: Any): String = x match { case i: Int if i > 10 && i % 2 == 0 => "greater than 10 and even" case i: Int if i > 10 && i % 2 != 0 => "greater than 10 and odd" case i: Int if i < 10 => "less than 10" case _ => "not an integer" } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
greater than 10 and odd less than 10 not an integer
The following points need to be noted about the above example -
- The first case checks if the integer is greater than 10 and even. If true, it returns "greater than 10 and even".
- The second case checks if the integer is greater than 10 and odd. If true, it returns "greater than 10 and odd".
- The third case checks if the integer is less than 10. If true, it returns "less than 10".
- The fourth case catches all other values and returns "not an integer".
Guards in Case Classes
Case classes can also benefit from using guards in pattern matching to add additional conditions.
Example
case class Person(name: String, age: Int) object Demo { def main(args: Array[String]): Unit = { val alice = Person("Alice", 25) val bob = Person("Bob", 32) val charlie = Person("Charlie", 32) for (person <- List(alice, bob, charlie)) { person match { case Person(name, age) if age < 30 => println(s"Hi $name, you are young!") case Person(name, age) if age >= 30 => println(s"Hi $name, you are experienced!") } } } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Hi Alice, you are young! Hi Bob, you are experienced! Hi Charlie, you are experienced!
The following points need to be noted about the above example -
- The first case checks if the age of person is less than 30. If true, it returns a message indicating youth.
- The second case checks if the age of person is 30 or greater. If true, it returns a message indicating experience.
Scala Guards Summary
- Guards are powerful constructs in Scala that enhance pattern matching by adding conditions to patterns.
- Guards can be used with if, case, and pattern matching
- You can specify multiple guard conditions to create more complex and precise pattern matches.
- Guards can be used in case classes, providing flexibility in pattern matching.
- Guards can be used in list and tuple matching to apply conditions based on the elements of these collections.