← Back to list

Swift Rewind : The Fundamentals of Data Modeling

Season 3 — Episode 3: Enums Unpacked with Associated Values.

Krishna Panchal · 2026-03-28 13:30 · 0 claps · 3.2 min read
#enum-associated-value #swift-enums-explained #master-enums-in-swift #swift-programming #swift-rewind
Open on Medium ↗
Wiki topics: 💻 · Programming 📱 · Mobile Development 🔒 · Cybersecurity 🔧 · Data Engineering

Swift Rewind : The Fundamentals of Data Modeling

Season 3 — Episode 3: Enums Unpacked with Associated Values.

Swift enums don’t just represent a fixed set of states — they can also store data along with each case using associated values. This makes them incredibly powerful for modeling real-world scenarios.

What are Associated Values?

Associated values let you attach additional data to enum cases. Each case can have different types and amounts of data.

// Let’s say we want to represent different shapes, each with its own properties:
enum ShapeDimensions {
    case square(side: Double) 
    case rectangle(width: Double, height: Double) 
    func area() -> Double {
        // Using Swift's pattern matching to bind self's associated value with a new variable ( or variables) 
        switch self {
        case let .square(side):
            return side * side

        case let .rectangle(width, height):
            return width * height
        }
    }
}

let squareShape = ShapeDimensions.square(side: 10.0)
let rectShape = ShapeDimensions.rectangle(width: 5.0, height: 10.0)

//Calling area() on instances created 
print("Square area = \(squareShape.area())")
print("Rectangle area = \(rectShape.area())")

🌟 How It Works? — switch is used to pattern match enum cases. let binds associated values to local variables. You can then use those values directly inside the case. Then creating Instances with associated values which requires to specify both case and an appropriate associated value for that case.

Well not All Cases Need Associated Values — Enums can mix cases with and without associated values.

enum ShapeDimensions {
    case point // point has no associated value - it is dimensionless
    case square(side: Double)
    case rectangle(width: Double, height: Double)

    func area() -> Double {
        switch self {
        case .point:
            return 0

        case let .square(side):
            return side * side

        case let .rectangle(width, height):
            return width * height
        }
    }
}

let pointShape = ShapeDimensions.point
print("Point area = \(pointShape.area())")

Overall, swift has ability to directly model custom data using your own type in this way is extremely powerful.

Challenge 🚀

Let’s level up our enum skills by adding a perimeter() method & supporting a new shape: right triangle in our ShapeDimensions enum.

enum ShapeDimensions {
    case point
    case square(side: Double)
    case rectangle(width: Double, height: Double)
    case rightTriangle(base: Double, height: Double, hypotenuse: Double)

    func area() -> Double {
        switch self {
        case .point:
            return 0
        case let .square(side):
            return side * side
        case let .rectangle(width, height):
            return width * height
        case let .rightTriangle(base, height, _):
            return 0.5 * base * height
        }
    }

    func perimeter() -> Double {
        switch self {
        case .point:
            return 0
        case let .square(side):
            return 4 * side
        case let .rectangle(width, height):
            return 2 * (width + height)
        case let .rightTriangle(base, height, hypotenuse):
            return base + height + hypotenuse
        }
    }
}

// TEST SOLUTION
let square = ShapeDimensions.square(side: 5)
let rectangle = ShapeDimensions.rectangle(width: 4, height: 6)
let triangle = ShapeDimensions.rightTriangle(base: 3, height: 4, hypotenuse: 5)
let point = ShapeDimensions.point

print("Square → Area:", square.area(), "Perimeter:", square.perimeter())
print("Rectangle → Area:", rectangle.area(), "Perimeter:", rectangle.perimeter())
print("Triangle → Area:", triangle.area(), "Perimeter:", triangle.perimeter())
print("Point → Area:", point.area(), "Perimeter:", point.perimeter())
// OUTPUT
Square → Area: 25.0 Perimeter: 20.0  
Rectangle → Area: 24.0 Perimeter: 20.0  
Triangle → Area: 6.0 Perimeter: 12.0  
Point → Area: 0.0 Perimeter: 0.0  

🌟 Recursive Enumerations (For the Curious 🧠)

Sometimes, an enum needs to reference itself — this is called a recursive enumeration.

// FamilyTree is recursive because its cases use FamilyTree as an associated value.
indirect enum FamilyTree {
    case noKnownParents
    case oneKnownParent(name: String, ancestors: FamilyTree)
    case twoKnownParents(
        fatherName: String,
        paternalAncestors: FamilyTree,
        motherName: String,
        maternalAncestors: FamilyTree
    )
}

// Usage
let family = FamilyTree.twoKnownParents(fatherName: "Fred Sr.", 
    paternalAncestors: .oneKnownParent(
        name: "Beth",
        ancestors: .noKnownParents
    ), motherName: "Marsha", maternalAncestors: .noKnownParents
)

But wait why we mentioned “indirect”? — Without indirect, Swift wouldn’t know how much memory to allocate.

Why is that so? — Because each case contains another FamilyTree, which contains another… and so on → infinite size problem. Mentioning indirect solves this by storing the associated value via a reference (pointer). Keeping the enum size fixed and manageable.

// Alternative: Apply indirect to Specific Cases
enum FamilyTree {
    case noKnownParents
    indirect case oneKnownParent(name: String, ancestors: FamilyTree)
    indirect case twoKnownParents(
        fatherName: String,
        paternalAncestors: FamilyTree,
        motherName: String,
        maternalAncestors: FamilyTree
    )
}

Recursive enums are perfect for modeling nested or tree-like data, such as: Family trees, File systems, UI hierarchies. And indirect makes it all possible by avoiding infinite memory issues.

⭐️ You’ve just completed Episode 3 of Season 3:

In this episode, we explored enums with associated values, learned how to model real-world data more flexibly, and even touched on recursive enums to represent nested structures.

Stay tuned — more calm, clear, and practical Swift concepts are coming next. Let’s keep rewinding Swift, one clean concept at a time.

💬 Found this helpful? Give this post a like and share it with a fellow iOS developer revisiting Swift fundamentals.


메타데이터
post_id
7fbd939ab8cb
slug
swift-rewind-the-fundamentals-of-data-modeling-7fbd939ab8cb
url
https://medium.com/@krishhna.ios/swift-rewind-the-fundamentals-of-data-modeling-7fbd939ab8cb
canonical_url
https://medium.com/@krishhna.ios/swift-rewind-the-fundamentals-of-data-modeling-7fbd939ab8cb
author_url
https://medium.com/@krishhna.ios
status
ok
fetched_at
2026-06-23 17:05:31