Skip to main content

Swift Enum 列舉型別

Swiftenum(列舉)是一個強大的型別,用來定義一組有限的狀態或選項。它比傳統的常數更安全、更易維護。

📋 目錄

基本語法

簡單的 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 指定原始值,支援 IntStringCharacter 等型別:

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

💡 最佳實踐

  1. 使用有意義的名稱:讓 enum 名稱清楚表達其用途
  2. 善用 switch:確保所有 case 都被處理
  3. 原始值 vs 關聯值
    • 原始值:當每個 case 都有固定的值時使用
    • 關聯值:當每個 case 需要攜帶不同資料時使用
  4. 添加方法:為 enum 添加實用的計算屬性和方法
  5. 遵循命名慣例:使用 camelCase,case 名稱使用小寫開頭