any P (existential): trade-offs & dynamic dispatch
Use any P to store or pass heterogeneous conformers behind a protocol. Understand dynamic dispatch, boxing, and limitations with associated types / Self requirements.
What is an existential?
Existentials (any P) hold any value conforming to P. They enable heterogenous storage and dynamic dispatch, with some restrictions.
- Great for mixed collections
- Dynamic dispatch via protocol witness tables
- Limitations with associated types/Self
Heterogeneous collection
any Shape lets you store different conformers together and call protocol methods via dynamic dispatch.
protocol Shape { func area() -> Double }
struct Circle: Shape { let r: Double; func area() -> Double { .pi * r * r } }
struct Square: Shape { let s: Double; func area() -> Double { s * s } }
// Heterogeneous array using ANY Shape
let shapes: [any Shape] = [Circle(r: 1), Square(s: 2), Circle(r: 0.5)]
let total = shapes.reduce(0) { $0 + $1.area() } // dynamic dispatch
print(String(format: "%.2f", total))All lessons in this course
- some P (opaque result types): hiding concrete types
- any P (existential): trade-offs & dynamic dispatch
- Choosing between some, any, and generics