This doc page is specific to Scala 3, and may cover new concepts not available in Scala 2. Unless otherwise stated, all the code examples in this page assume you are using Scala 3.
Used on types, the &
operator creates a so called intersection type.
The type A & B
represents values that are both of the type A
and of the type B
at the same time.
For instance, the following example uses the intersection type Resettable & Growable[String]
:
trait Resettable:
def reset(): Unit
trait Growable[A]:
def add(a: A): Unit
def f(x: Resettable & Growable[String]): Unit =
x.reset()
x.add("first")
In the method f
in this example, the parameter x
is required to be both a Resettable
and a Growable[String]
.
The members of an intersection type A & B
are all the members of A
and all the members of B
.
Therefore, as shown, Resettable & Growable[String]
has member methods reset
and add
.
Intersection types can be useful to describe requirements structurally.
That is, in our example f
, we directly express that we are happy with any value for x
as long as it’s a subtype of both Resettable
and Growable
.
We did not have to create a nominal helper trait like the following:
trait Both[A] extends Resettable with Growable[A]
def f(x: Both[String]): Unit
trait Both[A] extends Resettable, Growable[A]
def f(x: Both[String]): Unit
There is an important difference between the two alternatives of defining f
: While both allow f
to be called with instances of Both
, only the former allows passing instances that are subtypes of Resettable
and Growable[String]
, but not of Both[String]
.
Note that
&
is commutative:A & B
is the same type asB & A
.
Contributors to this page:
Contents
- Introduction
- Scala Features
- Why Scala 3?
- A Taste of Scala
- Hello, World!
- The REPL
- Variables and Data Types
- Control Structures
- Domain Modeling
- Methods
- First-Class Functions
- Singleton Objects
- Collections
- Contextual Abstractions
- Toplevel Definitions
- Summary
- A First Look at Types
- String Interpolation
- Control Structures
- Domain Modeling
- Tools
- OOP Modeling
- FP Modeling
- Methods
- Method Features
- Main Methods in Scala 3
- Summary
- Functions
- Anonymous Functions
- Function Variables
- Partial Functions
- Eta-Expansion
- Higher-Order Functions
- Write Your Own map Method
- Creating a Method That Returns a Function
- Summary
- Packaging and Imports
- Scala Collections
- Collections Types
- Collections Methods
- Summary
- Functional Programming
- What is Functional Programming?
- Immutable Values
- Pure Functions
- Functions Are Values
- Functional Error Handling
- Summary
- Types and the Type System
- Inferred Types
- Generics
- Intersection Types
- Union Types
- Algebraic Data Types
- Variance
- Opaque Types
- Structural Types
- Dependent Function Types
- Other Types
- Contextual Abstractions
- Extension Methods
- Context Parameters
- Context Bounds
- Given Imports
- Type Classes
- Multiversal Equality
- Implicit Conversions
- Summary
- Concurrency
- Scala Tools
- Building and Testing Scala Projects with sbt
- Worksheets
- Interacting with Java
- Scala for Java Developers
- Scala for JavaScript Developers
- Scala for Python Developers
- Where To Go Next