
- 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 - Union Types
Scala Union Types is used to define a type that can be one of various possible types. So you can have more flexible type definitions. Union type can reduce the need for overloading methods. These are used when a function can accept multiple different types as parameters and return multiple different types.
Declaring Union Types
The following is the syntax for declaring a union type variable.
Syntax
def exampleMethod(x: Int | String): Unit = { x match { case i: Int => println(s"Integer: $i") case s: String => println(s"String: $s") } }
Here, exampleMethod is declared with a parameter x that can be either an Int or a String. The union type Int | String specifies that x can be of either type.
Union Types in Methods
Below is an example program showing how to create and use a method with a union type parameter.
Example
object Demo { def main(args: Array[String]) = { def exampleMethod(x: Int | String): Unit = { x match { case i: Int => println(s"Integer: $i") case s: String => println(s"String: $s") } } // Call method with an integer exampleMethod(42) // Call method with a string exampleMethod("Scala") } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Integer: 42 String: Scala
Union Types in Function Parameters
Union types can also be used in function parameters. So functions can accept arguments of different types.
Example
Try following example of union types in function parameters -
object Demo { def main(args: Array[String]) = { def processInput(input: Int | Double | String): Unit = { input match { case i: Int => println(s"Processing Int: $i") case d: Double => println(s"Processing Double: $d") case s: String => println(s"Processing String: $s") } } // Call function with an integer processInput(10) // Call function with a double processInput(3.14) // Call function with a string processInput("Hello, Scala!") } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Processing Int: 10 Processing Double: 3.14 Processing String: Hello, Scala!
Union Types with Type Aliases
You can use type aliases to simplify the usage of union types. It is used when these are used frequently.
Example
Try following example of union types with type aliases -
object Demo { type IntOrString = Int | String def main(args: Array[String]) = { def printValue(value: IntOrString): Unit = { value match { case i: Int => println(s"Integer: $i") case s: String => println(s"String: $s") } } // Call function with an integer printValue(100) // Call function with a string printValue("Scala Union Types") } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Integer: 100 String: Scala Union Types
Returning Union Types from Methods
You can use union types as return types for methods. So a method can return different types based on some condition.
Example
Try following example of returning union type from method -
object Demo { def getValue(flag: Boolean): Int | String = { if (flag) 42 else "Scala" } def main(args: Array[String]) = { // Call method with true println(getValue(true)) // Call method with false println(getValue(false)) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
42 Scala
Union Types with Higher-Order Functions
You can use union types combined with higher-order functions to process elements of different types in a collection.
Example
Try following example of union types in higher order function -
object Demo { def main(args: Array[String]) = { val mixedList: List[Int | String] = List(1, "two", 3, "four") mixedList.foreach { case i: Int => println(s"Integer: $i") case s: String => println(s"String: $s") } // Transform the list elements val transformedList = mixedList.map { case i: Int => i * 2 case s: String => s.toUpperCase } println(transformedList) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Integer: 1 String: two Integer: 3 String: four List(2, TWO, 6, FOUR)
Union Types with Default Parameter Values
You can also use union types with default parameter values in functions and methods. So, there will be flexibility in how the function can be called. So, functions can handle different types of input with default values.
Example
The following example demonstrates union types with default parameter values –
object Demo { def main(args: Array[String]) = { def displayMessage(message: Int | String = "Default Message"): Unit = { message match { case i: Int => println(s"Integer: $i") case s: String => println(s"String: $s") } } // Call function with default parameter displayMessage() // Call function with an integer displayMessage(42) // Call function with a string displayMessage("Hello Scala") } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
String: Default Message Integer: 42 String: Hello Scala
Using Union Types in Constructors
You can use union types in class constructors for flexible initialization of class instances with different types.
Example
Try following example of union types in constructor -
object Demo { class Container(value: Int | String) { def display(): Unit = { value match { case i: Int => println(s"Integer: $i") case s: String => println(s"String: $s") } } } def main(args: Array[String]) = { // Create instances with different types val intContainer = new Container(42) val stringContainer = new Container("Scala") // Display values intContainer.display() stringContainer.display() } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Integer: 42 String: Scala
Union Types in Collections
You can use union types within collections, for lists, sets, and other collections to hold elements of different types. So, there will be flexibility for various data types in a unified collection.
Example
Try following example of union types in collection -
object Demo { def main(args: Array[String]) = { val collection: List[Int | String] = List(1, "two", 3, "four") collection.foreach { case i: Int => println(s"Integer: $i") case s: String => println(s"String: $s") } } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Integer: 1 String: two Integer: 3 String: four
Union Types Summary
- Union types in Scala are used for more flexible type definitions using variables that can be one of various types.
- You can use union types in method parameters, function parameters, and collections.
- Type aliases can simplify the usage of union types.
- Union types can reduce the need for overloading methods.
- Union types can be used as return types, in case classes, and with higher-order functions to process elements of different types.