Swift Enum 列舉型別
在 Swift 裡 enum(列舉)是一個強大的型別,用來定義一組有限的狀態或選項。它比傳統的常數更安全、更易維護。
📋 目錄
基本語法
簡單的 enum 定義
enum Direction {
case north
case south
case east
case west
}
// 使用
let dir = Direction.north
多個 case 一行寫法
enum Direction {
case north, south, east, west
}
搭配 Switch 使用
switch 是處理 enum 最常見的方式,Swift 會確保所有 case 都被處理:
enum Direction {
case north, south, east, west
}
func move(_ direction: Direction) {
switch direction {
case .north:
print("Go up")
case .south:
print("Go down")
case .east:
print("Go right")
case .west:
print("Go left")
}
}
move(.east) // 印出 Go right
原始值 (Raw Value)
可以為 enum 的每個 case 指定原始值,支援 Int、String、Character 等型別:
enum Planet: Int {
case mercury = 1
case venus // 自動 = 2
case earth // 自動 = 3
case mars // 自動 = 4
}
// 從原始值建立 enum
let earth = Planet(rawValue: 3)
print(earth!) // earth
// 取得原始值
print(Planet.earth.rawValue) // 3
String 原始值
enum HTTPMethod: String {
case get = "GET"
case post = "POST"
case put = "PUT"
case delete = "DELETE"
}
print(HTTPMethod.get.rawValue) // "GET"
關聯值 (Associated Value)
讓 enum 攜帶額外資訊,每個 case 可以有不同的資料型別:
enum NetworkResult {
case success(data: String)
case failure(error: Error)
case loading
}
let result: NetworkResult = .success(data: "OK")
switch result {
case .success(let data):
print("成功,資料:\(data)")
case .failure(let error):
print("失敗,錯誤:\(error)")
case .loading:
print("載入中...")
}
多種關聯值範例
enum APIResponse {
case success(data: [String: Any])
case error(code: Int, message: String)
case networkError(Error)
}
let response: APIResponse = .error(code: 404, message: "Not Found")
switch response {
case .success(let data):
print("資料:\(data)")
case .error(let code, let message):
print("錯誤 \(code):\(message)")
case .networkError(let error):
print("網路錯誤:\(error)")
}
實際應用範例
完整的 TankStatus 實作
public enum TankStatus: UInt8, Sendable {
/// Status is undefined or unknown (255).
case undefined = 255
/// The tank is empty (1).
case empty = 1
/// The tank is one-third full (2).
case oneThird = 2
/// The tank is two-thirds full (3).
case twoThird = 3
/// The tank is completely full (4).
case full = 4
/// 自定義初始化器,處理不同的輸入值
init?(rawValue: Int8) {
switch rawValue {
case 0, 1:
self = .empty
case 2:
self = .oneThird
case 3:
self = .twoThird
case 4:
self = .full
default:
return nil
}
}
/// 轉換為人類可讀的字串
public var stringRepresentation: String {
switch self {
case .undefined:
return "Undefined"
case .empty:
return "Empty"
case .oneThird:
return "One-Third"
case .twoThird:
return "Two-Third"
case .full:
return "Full"
}
}
/// 取得百分比
public var percentage: Int {
switch self {
case .undefined:
return 0
case .empty:
return 0
case .oneThird:
return 33
case .twoThird:
return 67
case .full:
return 100
}
}
}
// 使用範例
let status = TankStatus(rawValue: 3)
print(status?.stringRepresentation) // "Two-Third"
print(status?.percentage) // 67
💡 最佳實踐
- 使用有意義的名稱:讓 enum 名稱清楚表達其用途
- 善用 switch:確保所有 case 都被處理
- 原始值 vs 關聯值:
- 原始值:當每個 case 都有固定的值時使用
- 關聯值:當每個 case 需要攜帶不同資料時使用
- 添加方法:為 enum 添加實用的計算屬性和方法
- 遵循命名慣例:使用 camelCase,case 名稱使用小寫開頭