0
0
Swiftprogramming~10 mins

Type erasure concept in Swift - Step-by-Step Execution

Choose your learning style9 modes available
Concept Flow - Type erasure concept
Define Protocol with Associated Type
Create Concrete Types conforming to Protocol
Use Type Erasure Wrapper Struct
Hide Concrete Types behind Wrapper
Use Wrapper to store heterogeneous types uniformly
Access Protocol Methods without exposing type details
Type erasure hides specific types behind a wrapper to use different concrete types uniformly through a protocol with associated types.
Execution Sample
Swift
protocol Shape {
  associatedtype Color
  func draw() -> String
}

struct Circle: Shape {
  typealias Color = Void
  func draw() -> String { "Circle" }
}

struct AnyShape: Shape {
  typealias Color = Void
  private let _draw: () -> String
  init<S: Shape>(_ shape: S) {
    _draw = shape.draw
  }
  func draw() -> String { _draw() }
}
This code defines a protocol with an associated type, a concrete type, and a type erasure wrapper to hide the concrete type.
Execution Table
StepActionEvaluationResult
1Define protocol Shape with associatedtype Color and draw()Protocol createdShape protocol ready
2Define struct Circle conforming to ShapeCircle implements draw()Circle ready
3Create AnyShape wrapper with closure _drawStore draw() of any ShapeAnyShape ready
4Initialize AnyShape with Circle instanceCapture Circle's draw()AnyShape stores Circle's draw()
5Call draw() on AnyShape instanceInvoke stored closure"Circle" string returned
6Use AnyShape to hold different Shape typesHide concrete typesUniform interface achieved
7ExitNo more stepsType erasure complete
💡 All steps executed to show how type erasure hides concrete types behind a uniform interface.
Variable Tracker
VariableStartAfter Step 4After Step 5Final
Circle instanceNot createdCreatedUsed in AnyShapeExists
AnyShape instanceNot createdCreated with CircleStores Circle's draw()Used to call draw()
_draw closureNot setSet to Circle.drawCalled to return "Circle"Holds Circle.draw
Key Moments - 3 Insights
Why do we need the AnyShape wrapper instead of using Circle directly?
Because protocols with associated types cannot be used as types directly, AnyShape hides the concrete type so we can store different Shapes uniformly (see execution_table step 4).
How does AnyShape call the draw() method of the wrapped type?
AnyShape stores a closure _draw that captures the draw() method of the concrete type, so calling draw() on AnyShape calls this stored closure (see execution_table step 5).
What does 'type erasure' mean in this context?
It means hiding the specific type details behind a wrapper so code can use different types through a common interface without knowing their exact types (see concept_flow).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 4, what does AnyShape store?
AThe concrete Circle instance directly
BA closure that calls Circle's draw() method
CThe protocol Shape itself
DNothing, it is empty
💡 Hint
Check the 'Evaluation' and 'Result' columns at step 4 in execution_table.
At which step does calling draw() on AnyShape return the string "Circle"?
AStep 5
BStep 4
CStep 3
DStep 6
💡 Hint
Look for when draw() is invoked and returns a value in execution_table.
If we add another Shape type, how would the variable _draw in AnyShape change?
AIt would store the old Circle's draw() method only
BIt would become nil
CIt would store a closure for the new type's draw() method
DIt would store the protocol Shape
💡 Hint
Refer to variable_tracker row for _draw closure and how it stores draw() methods.
Concept Snapshot
Type Erasure in Swift:
- Used to hide concrete types behind a protocol with associated types
- Wrap concrete types in a struct (e.g., AnyShape)
- Store protocol methods as closures inside wrapper
- Allows uniform use of different types
- Enables collections or variables of protocol type
- Key for working around Swift's protocol limitations
Full Transcript
Type erasure is a technique in Swift to hide the specific types of objects that conform to protocols with associated types. Because such protocols cannot be used directly as types, we create a wrapper struct like AnyShape. This wrapper stores the concrete type's methods as closures. When we call methods on the wrapper, it forwards the call to the stored closure, hiding the concrete type details. This allows us to use different concrete types uniformly through the wrapper. The execution steps show defining the protocol, creating a concrete type Circle, wrapping it in AnyShape, and calling draw() through the wrapper to get the expected output. Variables like the Circle instance and the closure _draw change as the program runs. Key moments clarify why the wrapper is needed and how it works. The quiz tests understanding of these steps and concepts.