0
0
Swiftprogramming~7 mins

Type erasure concept in Swift

Choose your learning style9 modes available
Introduction

Type erasure helps hide complex or different types behind a simple, common type. This makes code easier to use and understand.

When you want to store different types that follow the same protocol in one collection.
When you want to return a protocol type from a function but the protocol has associated types or self requirements.
When you want to simplify complex generic types for easier use in your code.
When you want to hide implementation details from users of your API.
Syntax
Swift
struct AnyExample: ExampleProtocol {
    private let _doSomething: () -> Void

    init<T: ExampleProtocol>(_ example: T) {
        _doSomething = example.doSomething
    }

    func doSomething() {
        _doSomething()
    }
}

Type erasure is usually done by creating a wrapper struct or class.

The wrapper stores the original type's behavior using closures or stored properties.

Examples
Two shapes with different types but same protocol.
Swift
protocol Shape {
    func area() -> Double
}

struct Circle: Shape {
    var radius: Double
    func area() -> Double {
        return Double.pi * radius * radius
    }
}

struct Square: Shape {
    var side: Double
    func area() -> Double {
        return side * side
    }
}
Type erasure wrapper hides the specific shape type.
Swift
struct AnyShape: Shape {
    private let _area: () -> Double

    init<T: Shape>(_ shape: T) {
        _area = shape.area
    }

    func area() -> Double {
        return _area()
    }
}
Store different shapes in one array using type erasure.
Swift
let shapes: [AnyShape] = [AnyShape(Circle(radius: 3)), AnyShape(Square(side: 4))]
for shape in shapes {
    print(shape.area())
}
Sample Program

This program shows how to use type erasure to store different shapes in one array and call their area method.

Swift
import Foundation

protocol Shape {
    func area() -> Double
}

struct Circle: Shape {
    var radius: Double
    func area() -> Double {
        return Double.pi * radius * radius
    }
}

struct Square: Shape {
    var side: Double
    func area() -> Double {
        return side * side
    }
}

struct AnyShape: Shape {
    private let _area: () -> Double

    init<T: Shape>(_ shape: T) {
        _area = shape.area
    }

    func area() -> Double {
        return _area()
    }
}

let shapes: [AnyShape] = [AnyShape(Circle(radius: 3)), AnyShape(Square(side: 4))]

for shape in shapes {
    print(String(format: "%.2f", shape.area()))
}
OutputSuccess
Important Notes

Type erasure helps when protocols have associated types or self requirements that prevent direct use.

It adds a small performance cost due to indirection but improves code flexibility.

Summary

Type erasure hides specific types behind a common interface.

It allows storing and using different types uniformly.

It is useful for protocols with associated types or complex generics.