Swift 錯誤處理 (Error Handling)

Swift 提供了完善的錯誤處理機制,讓你能夠優雅地應對程式執行過程中可能發生的意外情況 (例如檔案讀取失敗、網路斷線)。

定義錯誤

在 Swift 中,任何遵循 Error 協定的型別都可以用來表示錯誤。通常我們會使用 Enum 來定義一組相關的錯誤。

enum VendingMachineError: Error {
    case invalidSelection
    case insufficientFunds(coinsNeeded: Int)
    case outOfStock
}

拋出錯誤 (Throwing Errors)

在函式定義後面加上 throws 關鍵字,表示這個函式可能會拋出錯誤。這種函式稱為 Throwing Function

func vend(itemNamed name: String) throws {
    guard let item = inventory[name] else {
        throw VendingMachineError.invalidSelection
    }
    
    guard item.count > 0 else {
        throw VendingMachineError.outOfStock
    }
    
    // ... 其他邏輯
}

處理錯誤

當一個函式拋出錯誤時,你必須處理它。主要有幾種方式:

1. 使用 do-catch

這是最完整的處理方式。

do {
    try vend(itemNamed: "Candy Bar")
    print("購買成功!")
} catch VendingMachineError.invalidSelection {
    print("無效的選擇")
} catch VendingMachineError.outOfStock {
    print("缺貨中")
} catch {
    print("發生未預期的錯誤: \(error)")
}

注意:在呼叫 throwing function 時,必須在前面加上 try 關鍵字。

2. 將錯誤轉換為 Optional (try?)

如果你不在乎錯誤的具體內容,只想知道成功與否,可以使用 try?。如果拋出錯誤,表達式結果為 nil

let result = try? vend(itemNamed: "Chips") 
// result 是 Void? 型別 (因為 vend 回傳 Void)

3. 禁止錯誤傳遞 (try!)

這是一種危險的操作。它告訴編譯器:「我知道這個函式理論上會 throw,但我保證這次執行絕對不會。」

如果真的拋出錯誤了,程式會直接當機。

// 只有在像是讀取預設圖檔,確定檔案一定存在時才使用
let photo = try! loadImage(atPath: "./Resources/John.jpg")