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)
枚举成员可以有关联的原始值(必须是同一类型,如 Int、String、Character、Double 等)。
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 枚举、泛型枚举、错误处理等),欢迎继续提问!