enum Name { case a, b, c } is the simplest form, similar to a plain enum in most languages. The genuinely distinctive feature is associated values: each case can specify its own, independently-shaped payload — case success(String) alongside case failure(Error) alongside case loading (no payload at all), all coexisting in one enum type. Extracting the associated value requires pattern matching, typically via switch or if case. Raw values (enum Direction: Int { case north = 0 }) are a separate, simpler feature for giving each case a fixed underlying value, useful for serialization or interop, but mutually exclusive with associated values on the same enum.
Associated values: each case with its own payload
success carries a String, failure carries an Error, loading carries nothing at all — three genuinely different shapes, coexisting under one NetworkResult type.
enum NetworkResult {
case success(String)
case failure(Error)
case loading
}
let result = NetworkResult.success("Data loaded")Extracting associated values with switch
let data inside the case pattern extracts and names the associated value directly — no separate unwrapping step needed, and the compiler still verifies all three cases are handled.
switch result {
case .success(let data):
print("Got: \(data)")
case .failure(let error):
print("Error: \(error)")
case .loading:
print("Still loading...")
}
// omitting any case above would be a COMPILE ERROR — exhaustiveness still appliesRaw values: a fixed underlying value per case
Raw values are a separate, simpler mechanism from associated values — useful specifically for interop or serialization, where each case needs one fixed, known underlying value rather than dynamic per-instance data.
enum Direction: Int {
case north = 0
case east = 90
case south = 180
case west = 270
}
let heading = Direction.east
print(heading.rawValue) // 90