錯誤處理基礎知識

Swift 中的函式可能返回值,丟擲錯誤 或兩者:

func reticulateSplines()                // no return value and no error
func reticulateSplines() -> Int         // always returns a value
func reticulateSplines() throws         // no return value, but may throw an error
func reticulateSplines() throws -> Int  // may either return a value or throw an error

任何符合 ErrorType 協議 (包括 NSError 物件)的值都可以作為錯誤丟擲。列舉提供了一種定義自定義錯誤的便捷方法:

Version <= 2.2

enum NetworkError: ErrorType {
    case Offline
    case ServerError(String)
}

Version = 3.0

enum NetworkError: Error {
    // Swift 3 dictates that enum cases should be `lowerCamelCase`
    case offline
    case serverError(String)
}

錯誤表示程式執行期間出現非致命故障,並使用專用控制流構造 do / catchthrowtry 進行處理。

func fetchResource(resource: NSURL) throws -> String {
    if let (statusCode, responseString) = /* ...from elsewhere...*/ {
        if case 500..<600 = statusCode {
            throw NetworkError.serverError(responseString)
        } else {
            return responseString
        }
    } else {
        throw NetworkError.offline
    }
}

可以通過 do / catch 捕獲錯誤:

do {
    let response = try fetchResource(resURL)
    // If fetchResource() didn't throw an error, execution continues here:
    print("Got response: \(response)")
    ...
} catch {
    // If an error is thrown, we can handle it here.
    print("Whoops, couldn't fetch resource: \(error)")
}

必須使用 trytry?try! 呼叫任何可以丟擲錯誤的函式 :

// error: call can throw but is not marked with 'try'
let response = fetchResource(resURL)

// "try" works within do/catch, or within another throwing function:
do {
    let response = try fetchResource(resURL)
} catch {
    // Handle the error
}

func foo() throws {
    // If an error is thrown, continue passing it up to the caller.
    let response = try fetchResource(resURL)
}

// "try?" wraps the function's return value in an Optional (nil if an error was thrown).
if let response = try? fetchResource(resURL) {
    // no error was thrown
}

// "try!" crashes the program at runtime if an error occurs.
let response = try! fetchResource(resURL)