以擼代碼的形式學(xué)習(xí)Swift-18:錯誤處理(Error handling)

錯誤處理(Error handling)是響應(yīng)錯誤以及從錯誤中恢復(fù)的過程狠轻。

1 表示并拋出錯誤

Error空協(xié)議表明該類型可以用于錯誤處理

enum VendingMachineError: Error {
    case InvalidSelection //選擇無效 
    case InsufficientFunds(coinsNeeded: Int) //金額不足
    case OutOfStock //缺貨
}
throw VendingMachineError.InsufficientFunds(coinsNeeded: 5)

2 處理錯誤

為了標(biāo)識出代碼中可能會拋出錯誤的地方抄伍,在調(diào)用一個能拋出錯誤的函數(shù)呢蛤、方法或者構(gòu)造器之前,加上 try 關(guān)鍵字危融,或者 try? 或 try!這種變體渡八。

四個處理錯誤的方式:

  1. 用throwing函數(shù)傳遞錯誤

throwing函數(shù): 在函數(shù)聲明的參數(shù)列表之后加上 throws 關(guān)鍵字,為了表示一個函數(shù)、方法或構(gòu)造器可以拋出錯誤晃跺。

    func canThrowErrors() throws -> String
    func cannotThrowErrors() -> String

一個 throwing 函數(shù)可以在其內(nèi)部拋出錯誤揩局,并將錯誤傳遞到函數(shù)被調(diào)用時的作用域。
只有 throwing 函數(shù)可以傳遞錯誤掀虎。任何在某個非throwing函數(shù)內(nèi)部拋出的錯誤只能在函數(shù)內(nèi)部處理凌盯。

struct Item {
    var price: Int
    var count: Int
}
class VendingMachine {
    var inventory = [
        "Candy Bar": Item(price: 12, count: 7),
        "Chips": Item(price: 10, count: 4),
        "Pretzels": Item(price: 7, count: 11)
    ]
    var coinsDeposited = 0
    func dispenseSnack(snack: String) {
        print("Dispensing \(snack)")
    }
    func vend(itemNamed name: String) throws {
        guard let item = inventory[name] else {
            throw VendingMachineError.InvalidSelection
        }
        guard item.count > 0 else {
            throw VendingMachineError.OutOfStock
        }
        guard item.price <= coinsDeposited else {
            throw VendingMachineError.InsufficientFunds(coinsNeeded: item.price - coinsDeposited)
        }
        coinsDeposited -= item.price
        var newItem = item
        newItem.count -= 1
        inventory[name] = newItem
        dispenseSnack(snack: name)
    }
}
let favoriteSnacks = [
    "Alice": "Chips",
    "Bob": "Licorice",
    "Eve": "Pretzels",
]
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
    let snackName = favoriteSnacks[person] ?? "Candy Bar"
    try vendingMachine.vend(itemNamed: snackName)
}
//  throwing構(gòu)造器能像throwing函數(shù)一樣傳遞錯誤。
struct PurchasedSnack {
    let name: String
    init(name: String, vendingMachine: VendingMachine) throws {
        try vendingMachine.vend(itemNamed: name)
        self.name = name
    }
}
  1. 用 Do-Catch 處理錯誤
var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8
do {
    try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
} catch VendingMachineError.InvalidSelection {
    print("Invalid Selection.")
} catch VendingMachineError.OutOfStock {
    print("Out of Stock.")
} catch VendingMachineError.InsufficientFunds(let coinsNeeded) {
    print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")
}
// 打印 “Insufficient funds. Please insert an additional 2 coins.”
  1. 將錯誤轉(zhuǎn)換成可選值

如果 someThrowingFunction() 拋出一個錯誤烹玉, x 和 y 的值是 nil驰怎,否則 x 和 y 的值就是該函數(shù)的返回值。
無論 someThrowingFunction() 的返回值類型是什么類型二打, x 和 y 都是這個類型的可選類型县忌。
x,y的兩種形式類似继效,try? 更簡潔症杏。

func someThrowingFunction() throws -> Int {
    // ...
    return 0
}
let x = try? someThrowingFunction()
let y: Int?
do {
    y = try someThrowingFunction()
} catch {
    y = nil
}
  1. 禁用錯誤傳遞

try! 禁止錯誤傳遞,如真有錯誤拋出瑞信,就出現(xiàn)運行錯誤厉颤。

let photo = try! loadImage("./Resources/John Appleseed.jpg")

3 指定清理操作

playground文件在andyRon/LearnSwift

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市凡简,隨后出現(xiàn)的幾起案子逼友,更是在濱河造成了極大的恐慌精肃,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帜乞,死亡現(xiàn)場離奇詭異司抱,居然都是意外死亡,警方通過查閱死者的電腦和手機挖函,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進店門状植,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人怨喘,你說我怎么就攤上這事津畸。” “怎么了必怜?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵肉拓,是天一觀的道長。 經(jīng)常有香客問我梳庆,道長暖途,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任膏执,我火速辦了婚禮驻售,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘更米。我一直安慰自己欺栗,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布征峦。 她就那樣靜靜地躺著迟几,像睡著了一般。 火紅的嫁衣襯著肌膚如雪栏笆。 梳的紋絲不亂的頭發(fā)上类腮,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天,我揣著相機與錄音蛉加,去河邊找鬼蚜枢。 笑死,一個胖子當(dāng)著我的面吹牛针饥,可吹牛的內(nèi)容都是我干的祟偷。 我是一名探鬼主播,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼打厘,長吁一口氣:“原來是場噩夢啊……” “哼修肠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起户盯,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤嵌施,失蹤者是張志新(化名)和其女友劉穎饲化,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吗伤,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡吃靠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了足淆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巢块。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖巧号,靈堂內(nèi)的尸體忽然破棺而出族奢,到底是詐尸還是另有隱情,我是刑警寧澤丹鸿,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布越走,位于F島的核電站,受9級特大地震影響靠欢,放射性物質(zhì)發(fā)生泄漏廊敌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一门怪、第九天 我趴在偏房一處隱蔽的房頂上張望骡澈。 院中可真熱鬧,春花似錦掷空、人聲如沸肋殴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疼电。三九已至嚼锄,卻和暖如春减拭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背区丑。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工拧粪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沧侥。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓可霎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宴杀。 傳聞我的和親對象是個殘疾皇子癣朗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,666評論 2 350

推薦閱讀更多精彩內(nèi)容