Swift 枚举

Swift 中的枚举(Enumeration)是一种强大的数据类型,用于定义一组相关的值,使得代码更安全、更易读。Swift 的枚举比 C 或 Objective-C 中的枚举更强大,支持关联值、原始值、方法、计算属性等。


基本语法

enum 枚举名 {
    case 值1
    case 值2
    case 值3
}

示例:方向

enum CompassPoint {
    case north
    case south
    case east
    case west
}

var direction = CompassPoint.north
direction = .south  // 简化写法(类型推断)

1. 原始值(Raw Values)

枚举成员可以有关联的原始值(必须是同一类型,如 IntStringCharacterDouble 等)。

enum Planet: Int {
    case mercury = 1
    case venus
    case earth
    case mars
}

// 自动递增
print(Planet.earth.rawValue) // 3

字符串原始值(常用)

enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}

从原始值创建枚举

if let somePlanet = Planet(rawValue: 3) {
    print(somePlanet) // earth
}

2. 关联值(Associated Values)

允许为每个 case 存储额外的数据(类型可以不同)。

enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("https://example.com")

解包关联值(switch)

switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
    print("UPC: \(numberSystem)-\(manufacturer)-\(product)-\(check)")
case .qrCode(let code):
    print("QR Code: \(code)")
}

绑定单个值

case let .qrCode(code):
    print(code)

3. 枚举方法和计算属性

enum Temperature {
    case celsius(Double)
    case fahrenheit(Double)
    case kelvin(Double)

    var inCelsius: Double {
        switch self {
        case .celsius(let value):
            return value
        case .fahrenheit(let value):
            return (value - 32) * 5 / 9
        case .kelvin(let value):
            return value - 273.15
        }
    }
}

let temp = Temperature.fahrenheit(98.6)
print(temp.inCelsius) // 37.0

4. 递归枚举(Recursive Enumeration)

使用 indirect 关键字,支持枚举包含自身。

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

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    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)
    }
}

print(evaluate(product)) // (5 + 4) * 2 = 18

5. 枚举作为状态机

enum TrafficLight {
    case red, yellow, green

    mutating func next() {
        switch self {
        case .red:    self = .green
        case .green:  self = .yellow
        case .yellow: self = .red
        }
    }
}

var light = TrafficLight.red
light.next()
print(light) // green

6. 枚举与协议

enum MediaType: CustomStringConvertible {
    case image, video, audio

    var description: String {
        switch self {
        case .image: return "图片"
        case .video: return "视频"
        case .audio: return "音频"
        }
    }
}

最佳实践总结

特性建议
命名枚举类型用大驼峰,case 用小驼峰
原始值适合固定映射(如状态码)
关联值适合灵活数据结构(如错误、解析结果)
switch总是处理所有 case(编译器会警告)
默认值可用 default 但建议显式列出

小技巧

// 所有 case 提取(iOS 13+)
enum Direction: CaseIterable {
    case up, down, left, right
}

for dir in Direction.allCases {
    print(dir)
}

如需更深入内容(如 Codable 枚举、泛型枚举、错误处理等),欢迎继续提问!

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部