Swift enums interview questions, with answers
Swift enums are far more capable than the named integers of C or Java's early enums: they can carry data, have methods and conform to protocols, and switch statements over them are checked for completeness. Interviewers ask about them because they sit at the centre of Swift's type system, including Optional and Result.
The answers below cover enums with methods, associated values, raw values, pattern matching, CaseIterable, recursive enums and how Optional is itself an enum, with code compiled with swiftc 6.4. Then take the free Swift diagnostic — ten questions across every Swift topic in the bank — to see which of these you can explain but not yet predict.
The questions, with answers
1.How are Swift enums different from enums in C?
In short: Swift enum cases are values of their own type, not integers, and enums can have methods, computed properties and protocol conformances.
A C enum is a set of named integer constants that can be mixed freely with other integers. A Swift enum defines a new type whose cases are its only possible values, so a Coin is always heads or tails and never an arbitrary number. Enums can have methods, computed properties, initializers and extensions, and they can conform to protocols, as flip below shows by switching over self and returning the other case.
enum Coin { case heads, tails func flip() -> Coin { switch self { case .heads: .tails case .tails: .heads } } } print(Coin.heads.flip()) // tails
2.What are associated values in Swift enums?
In short: Data attached to an individual enum case, such as a UPI id on a payment case, extracted by pattern matching.
Each case of an enum can carry its own values of any types, so one enum can model alternatives that hold different data: a cash payment needs nothing, while a UPI payment needs an id. The values are supplied when the case is created and extracted with a pattern, in a switch or with if case, as below. This makes enums with associated values the natural way to model states, results and messages, and it is how Result carries either a success value or an error.
enum Pay { case cash case upi(id: String) } let p = Pay.upi(id: "a@okbank") if case .upi(let id) = p { print(id) } // a@okbank
3.What are raw values in Swift enums?
In short: Fixed values of one type, such as String or Int, assigned to every case and read with the rawValue property.
An enum declared with a raw type, such as enum Size: String, gives each case a constant raw value of that type, readable with rawValue. For String raw types, a case without an explicit value uses its own name, which is why large prints large. Raw values must be literals and unique within the enum. They suit enums that map to external codes, such as JSON strings, API parameters or database values, and Codable encodes and decodes such enums through their raw values automatically.
enum Size: String { case small = "S", large } print(Size.small.rawValue) print(Size.large.rawValue) // S // large
4.How does pattern matching work in a Swift switch?
In short: Each case can match literals, ranges, tuples with _ wildcards, bound values and where conditions; the first matching case runs.
A Swift switch is not limited to comparing with constants. Cases can match tuples element by element, use _ to ignore an element, match ranges such as 1...9, bind parts of the value with let, and add conditions with where. The first case that matches runs, there is no implicit fall-through, and default catches every other value. The same patterns work in if case, guard case and for case, and in catch clauses.
let p = (0, 5) switch p { case (0, 0): print("origin") case (0, _): print("y axis") case (_, 0): print("x axis") default: print("elsewhere") } // y axis
5.What does CaseIterable do for a Swift enum?
In short: It makes the compiler generate allCases, a collection of every case in declaration order, for enums without associated values.
Adopting CaseIterable on an enum whose cases have no associated values makes Swift synthesize a static allCases property listing every case in the order they are declared. It is useful for building pickers and menus, iterating over all options in tests, or counting cases, and it stays correct automatically when cases are added. For enums with associated values, the property cannot be generated, since the values are unknown, but you can implement allCases yourself.
enum Day: CaseIterable { case mon, tue, wed } print(Day.allCases.count) print(Day.allCases.first!) // 3 // mon
6.What is an indirect enum in Swift?
In short: An enum marked indirect can have cases that contain the enum itself, which is needed for recursive structures such as expression trees.
Enums are value types, and a value cannot contain itself directly, because its size would be infinite. Marking the enum, or a single case, indirect tells Swift to store those associated values behind a reference, which makes recursive definitions possible. The code models arithmetic expressions in which an add case holds two further expressions, and a recursive function evaluates the tree with a switch. Indirect enums are a concise way to write trees, linked lists and parsers' syntax trees.
indirect enum Expr { case num(Int) case add(Expr, Expr) } func eval(_ e: Expr) -> Int { switch e { case .num(let n): n case .add(let a, let b): eval(a) + eval(b) } } let two = Expr.num(2) print(eval(.add(two, .num(3)))) // 5
7.Why is Optional an enum in Swift?
In short: Optional<Wrapped> is an enum with two cases, some(Wrapped) and none; nil and the ? syntax are shorthand for them.
Optional is defined in the standard library as an ordinary generic enum with a case some that carries the value and a case none. Writing Int? is shorthand for Optional<Int>, nil is shorthand for .none, and a plain value is wrapped in .some automatically. That is why optionals can be matched in a switch with .some and .none, and why methods such as map exist on them. It shows how much of Swift's safety comes from its type system rather than special rules in the compiler.
let x: Int? = .some(3) let y: Int? = .none print(x == 3, y == nil) // true true
How the diagnostic asks it
One question from the Swift bank, exactly as a sitting would show it. The bank has 3 on enums & pattern matching and 30 across Swift.
What does this Swift code print?
enum Shape { case circle(r: Double) case rect(w: Double, h: Double) } let s = Shape.rect(w: 2, h: 2) switch s { case .rect(let w, let h) where w == h: print("square") case .rect: print("rect") case .circle: print("circle") }
- 1rect
- 2squarecorrect
- 3square, then rect
- 4It does not compile: where cannot be used in a case
A switch tries its cases in order and runs only the first that matches. .rect(let w, let h) where w == h matches a rect and binds its associated values, and the where clause adds the condition that they are equal, which holds for 2 and 2, so it prints square. rect would print for a rect with different sides. Swift switches do not fall through, so square, then rect is wrong; fallthrough must be written explicitly. where clauses are allowed in case patterns, as in for-in loops and catch clauses.
Measure it
Reading answers tells you what’s true. A diagnostic tells you what you get wrong.
10 Swift questions across its topics, easy to hard, about fifteen minutes. You get a readiness figure with the arithmetic shown, the topics you missed named, and a practice set sized for today. Free: 1 diagnostic a month and 15 problems a day. No card.