Swift 的枚舉類型遠超 C/Objective-C 的簡單整數別名,它是一等類型,支援關聯值、原始值、方法、協議遵循等強大特性。本文將系統梳理 Swift 枚舉的聲明、調用、Switch 模式匹配、原始值、關聯值及遞歸枚舉等核心知識點,並配以實戰代碼示例。
使用 enum 關鍵字定義,命名遵循 UpperCamelCase,成員用 case 列舉:
enum Weekday {
case monday, tuesday, wednesday, thursday, friday, saturday, sunday
// 也可寫成多行,風格統一即可
}
注意:Swift 枚舉成員不會隱式賦予整數值,它們本身就是完整的值。
var day: Weekday = .sunday // 完整寫法
day = .monday // 類型上下文明確時,可省略類型名
Swift switch 必須窮盡所有情況,配合枚舉可獲編譯器安全保障:
let today = Weekday.saturday
switch today {
case .monday, .tuesday, .wednesday, .thursday, .friday:
print("工作日 💼")
case .saturday, .sunday:
print("周末 🎮")
// 無需 default,編譯器確認已窮盡
}
enum Season: Int {
case spring = 1, summer, autumn, winter // summer=2, autumn=3...
}
enum Direction: String {
case north = "N", south = "S", east = "E", west = "W"
}
if let season = Season(rawValue: 2) {
print("第 2 季節是 \(season)") // summer
}
print(Season.spring.rawValue) // 1
這是 Swift 枚舉最強大的特性之一,讓同一枚舉類型的不同成員攜帶不同類型/數量的數據:
enum TradeAction {
case buy(stock: String, amount: Int)
case sell(stock: String, amount: Int, price: Double)
case hold
}
let action = TradeAction.buy(stock: "AAPL", amount: 100)
switch action {
case .buy(let stock, let amount):
print("買入 \(amount) 股 \(stock)")
case .sell(let stock, let amount, let price):
print("賣出 \(amount) 股 \(stock) @ \(price)")
case .hold:
print("持有觀望")
}
使用 indirect 關鍵字標記遞歸成員:
indirect enum ArithmeticExpr {
case number(Int)
case add(ArithmeticExpr, ArithmeticExpr)
case multiply(ArithmeticExpr, ArithmeticExpr)
}
let expr = ArithmeticExpr.add(.number(2), .multiply(.number(3), .number(4)))
// 表示 2 + (3 * 4)
枚舉可定義方法、計算屬性,並遵循協議:
enum Device: String, CaseIterable {
case iPhone, iPad, mac, watch
var description: String {
"Apple 設備:\(rawValue)"
}
func launchYear() -> Int {
switch self {
case .iPhone: return 2007
case .iPad: return 2010
case .mac: return 1984
case .watch: return 2015
}
}
}
Device.allCases.forEach { print($0.description, "首發年份:", $0.launchYear()) }
Swift 枚舉是建模「有限狀態集合」的利器。善用關聯值可替代大量類層級,配合 switch 窮盡匹配,能在編譯期消除大量運行時錯誤。實戰中,建議優先考慮枚舉來表示業務狀態、網絡請求結果、UI 事件等場景。
下一期將深入講解 Swift 類與結構體的異同與選擇策略,敬請關注。