Swift Enum Deep Dive: RawValue Initialization, Implicit Values & Recursion
  • July 24, 2025

 


Raw Values

A raw value is a constant of a primitive type (like Int, String, or Double) that you assign to each enum case. This lets you convert between the enum and its underlying primitive representation.

enum Weekday: Int {
    case monday = 1
    case tuesday = 2
    case wednesday = 3
    case thursday = 4
    case friday = 5
    case saturday = 6
    case sunday = 7
}

print(Weekday.friday.rawValue)  // 5
  • Declare the raw-value type after the enum name (: Int).
  • Each case must have a unique raw value of that type.
  • Swift synthesizes a failable initializer init?(rawValue:) for you.

Implicitly Assigned Raw Values

When your raw-value type is Int or String, Swift can fill in missing values automatically.

Integer enums

If you give the first case an Int raw value, subsequent cases increment by one:

enum LogLevel: Int {
    case debug = 1
    case info, warning, error
}

print(LogLevel.warning.rawValue)  // 3

Here, info is 2, warning 3, and error 4 automatically.

String enums

If you omit raw values on a String enum, each case’s raw value defaults to its own name:

enum Planet: String {
    case mercury, venus, earth, mars
}

print(Planet.earth.rawValue)  // "earth"

This is especially handy for coding keys, API parameters, or user-facing strings.


Initializing from a Raw Value

Use the synthesized initializer init?(rawValue:) to attempt converting a primitive into your enum:

if let day = Weekday(rawValue: 3) {
    print("Day 3 is \(day)")  // "Day 3 is wednesday"
} else {
    print("No matching weekday")
}

// Failable: returns nil for out-of-range or mismatched values
let maybeDay = Weekday(rawValue: 10)  // nil

Because it’s failable (init?), you must unwrap safely (if let, guard let, etc.).


Recursive Enumerations

A recursive enum is one whose cases can hold instances of the same enum type—ideal for tree-like data structures. Mark the recursive cases with the indirect keyword:

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

You can also mark the entire enum as indirect:

indirect enum Expr {
    case number(Int)
    case plus(Expr, Expr)
    case times(Expr, Expr)
}

Evaluating a Recursive Enum

Define a function that walks the structure:

func evaluate(_ expr: ArithmeticExpression) -> Int {
    switch expr {
    case .number(let value):
        return value
    case .addition(let left, let right):
        return evaluate(left) + evaluate(right)
    case .multiplication(let left, let right):
        return evaluate(left) * evaluate(right)
    }
}

// Build ((5 + 4) * 2)
let expr = ArithmeticExpression.multiplication(
    .addition(.number(5), .number(4)),
    .number(2)
)
print(evaluate(expr))  // 18
  • The indirect keyword tells Swift to insert a level of indirection so the enum can refer to itself.
  • Recursive enums let you model nested, hierarchical data cleanly and safely.

Tips & Gotchas

  • Raw-value enums are best when each case has a fixed, primitive mapping (e.g., HTTP status codes, JSON keys).
  • Don’t mix associated values on a raw-value enum—Swift disallows it.
  • Use guard let x = MyEnum(rawValue: value) to validate external input.
  • Recursive enums can be memory-heavy; consider class-based trees or value-indirect structs for very deep structures.
YOU MIGHT ALSO LIKE...
MijickPopups Hero

  Popups Alerts Resizable Sheets Banners

SwiftUI Tooltip

This package provides you with an easy way to show tooltips over any SwiftUI view, since Apple does not provide ...

SimpleToast for SwiftUI

SimpleToast is a simple, lightweight, flexible and easy to use library to show toasts / popup notifications inside iOS or ...

SSToastMessage

Create Toast Views with Minimal Effort in SwiftUI Using SSToastMessage. SSToastMessage enables you to effortlessly add toast notifications, alerts, and ...

ToastUI

A simple way to show toast in SwiftUI   Getting Started • Documentation • Change Log