Swift12 - 錯誤處理聚磺、類型轉(zhuǎn)換坯台、嵌套類型

錯誤處理

錯誤用遵循 Error 協(xié)議的類型的值來表示

enum VendingMachineError: Error {
    case invalidSelection //選擇無效
    case insufficientFunds(coinsNeeded: Int) //金額不足
    case outOfStock //缺貨
}

在調(diào)用一個能拋出錯誤的函數(shù)、方法或者構造器之前瘫寝,加上 try 關鍵字蜒蕾,或者 try? 或 try! 這種變體。
一個標有 throws 關鍵字的函數(shù)被稱作 throwing 函數(shù)
func canThrowErrors() throws -> String

只有 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 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
        
    }
}

//do {
//    try expression
//    statements
//} catch pattern 1 {
//    statements
//} catch pattern 2 where condition {
//    statements
//} catch {
//    statements
//}

let favoriteSnacks = [
    "Alice": "Chips",
    "Bob": "Licorice",
    "Eve": "Pretzels",
]
// 調(diào)用加try關鍵字,并向上級拋出異常
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
    let snackName = favoriteSnacks[person] ?? "Candy Bar"
    try vendingMachine.vend(itemNamed: snackName)
}

var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8
do {
    try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
    print("Success! Yum.")
} 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.")
} catch {
    print("Unexpected error: \(error).")
}

類型轉(zhuǎn)換

使用 is 和 as 操作符實現(xiàn)暮屡。

class MediaItem {
    var name: String
    init(name: String) {
        self.name = name
    }
}

class Movie: MediaItem {
    var director: String
    init(name: String, director: String) {
        self.director = director
        super.init(name: name)
    }
}

class Song: MediaItem {
    var artist: String
    init(name: String, artist: String) {
        self.artist = artist
        super.init(name: name)
    }
}

let library = [
    Movie(name: "Casablanca", director: "Michael Curtiz"),
    Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
    Movie(name: "Citizen Kane", director: "Orson Welles"),
    Song(name: "The One And Only", artist: "Chesney Hawkes"),
    Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]// 數(shù)組 library 的類型被推斷為 [MediaItem]

在幕后 library 里存儲的媒體項依然是 Movie 和 Song 類型的撤摸。
但是,若你迭代它褒纲,依次取出的實例會是 MediaItem 類型的准夷,而不是 Movie 和 Song 類型。
為了讓它們作為原本的類型工作莺掠,你需要檢查它們的類型或者向下轉(zhuǎn)換它們到其它類型

檢查類型:

用類型檢查操作符(is)來檢查一個實例是否屬于特定子類型
計算數(shù)組 library 中 Movie 和 Song 類型的實例數(shù)量:

var moiveCount = 0
var songCount = 0

for item in library {
    if item is Movie {
        moiveCount += 1
    }else if item is Song {
        songCount += 1
    }
}
向下轉(zhuǎn)型

某類型的一個常量或變量可能在幕后實際上屬于一個子類衫嵌。當確定是這種情況時,你可以嘗試用類型轉(zhuǎn)換操作符(as? 或 as!)向下轉(zhuǎn)到它的子類型彻秆。
你不確定向下轉(zhuǎn)型可以成功時楔绞,用類型轉(zhuǎn)換的條件形式(as?)
只有你可以確定向下轉(zhuǎn)型一定會成功時,才使用強制形式(as!)

for item in library {
    if let movie = item as? Movie {
        print("Movie: \(movie.name), dir. \(movie.director)")
    }else if let song = item as? Song {
        print("Song: \(song.name), by \(song.artist)")
    }
}
Any 和 AnyObject 的類型轉(zhuǎn)換

Swift 為不確定類型提供了兩種特殊的類型別名:

  • Any 可以表示任何類型唇兑,包括函數(shù)類型墓律。
  • AnyObject 可以表示任何類類型的實例。

Any 類型可以表示所有類型的值幔亥,包括可選類型。Swift 會在你用 Any 類型來表示一個可選值的時候察纯,給你一個警告帕棉。
如果你確實想使用 Any 類型來承載可選值针肥,你可以使用 as 操作符顯式轉(zhuǎn)換為 Any,如下所示:

var things = [Any]()
let optionalNumber: Int? = 3
things.append(optionalNumber)        // 警告
things.append(optionalNumber as Any) // 沒有警告

嵌套類型

要在一個類型中嵌套另一個類型香伴,將嵌套類型的定義寫在其外部類型的 {} 內(nèi)慰枕,而且可以根據(jù)需要定義多級嵌套。

//例子
struct BlackjackCard {
    // 嵌套的Suit枚舉
    enum Suit: Character {
        case spades = "?", hearts = "?", diamonds = "?", clubs = "?"
    }
    
    //
    enum Rank: Int {
        case two = 2, three, four, five, six, seven, eight, nine, ten
        case jack, queen, king, ace
        struct Values {
            let first: Int, second: Int?
        }
    }
}
//引用嵌套類型
let heartsSymbol = BlackjackCard.Suit.hearts.rawValue
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末即纲,一起剝皮案震驚了整個濱河市具帮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌低斋,老刑警劉巖蜂厅,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異膊畴,居然都是意外死亡掘猿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門唇跨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稠通,“玉大人,你說我怎么就攤上這事买猖「拈伲” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵玉控,是天一觀的道長飞主。 經(jīng)常有香客問我,道長奸远,這世上最難降的妖魔是什么既棺? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮懒叛,結果婚禮上丸冕,老公的妹妹穿的比我還像新娘。我一直安慰自己薛窥,他們只是感情好胖烛,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诅迷,像睡著了一般佩番。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上罢杉,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天趟畏,我揣著相機與錄音,去河邊找鬼滩租。 笑死赋秀,一個胖子當著我的面吹牛利朵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猎莲,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼绍弟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了著洼?” 一聲冷哼從身側(cè)響起樟遣,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎身笤,沒想到半個月后豹悬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡展鸡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年屿衅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片莹弊。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡涤久,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忍弛,到底是詐尸還是另有隱情响迂,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布细疚,位于F島的核電站蔗彤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏疯兼。R本人自食惡果不足惜然遏,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吧彪。 院中可真熱鬧待侵,春花似錦、人聲如沸姨裸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽傀缩。三九已至那先,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赡艰,已是汗流浹背售淡。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人揖闸。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓苦掘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親楔壤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348