一、使用nil
- 可失敗初始化器
使用工廠方法
static func createWithMagicWords(words: String) -> Spell? {
if let incantation = MagicWords(rawValue: words) {
var spell = Spell()
spell.magicWords = incantation
return spell
}
else {
return nil
}
}
let first = Spell.createWithMagicWords("abracadabra")
let second = Spell.createWithMagicWords("ascend")使用初始化器
init?(words: String) {
if let incantation = MagicWords(rawValue: words) {
self.magicWords = incantation
}
else {
return nil
}
}
let first = Spell(words: "abracadabra")
let second = Spell(words: "ascend")
- guard 語(yǔ)句
init?(words: String) {
guard let incantation = MagicWords(rawValue: words) else {
return nil
}
self.magicWords = incantation
}
二、自定義錯(cuò)誤處理
do-try-catch 機(jī)制的關(guān)鍵字:
throwsdocatchtrydeferErrorType
- 定義錯(cuò)誤
enum ChangoSpellError: ErrorType {
case HatMissingOrNotMagical
case NoFamiliar
case FamiliarAlreadyAToad
case SpellFailed(reason: String)
case SpellNotKnownToWitch
}
- 遵守
ErrorType協(xié)議 - 通過(guò)關(guān)聯(lián)值綁定具體的錯(cuò)誤原因
- 定義方法
方法聲明(或協(xié)議方法聲明)添加
throws
func turnFamiliarIntoToad() throws -> Toad {
if let hat = hat {
if hat.isMagical { // When have you ever seen a Witch perform a spell without her magical hat on ? :]
if let familiar = familiar { // Check if witch has a familiar
if let toad = familiar as? Toad { // Check if familiar is already a toad - no magic required
return toad
} else {
if hasSpellOfType(.PrestoChango) {
if let name = familiar.name {
return Toad(name: name)
}
}
}
}
}
}
return Toad(name: "New Toad") // This is an entirely new Toad.
}-
方法實(shí)現(xiàn)拋出錯(cuò)誤
func turnFamiliarIntoToad() throws -> Toad {
guard let hat = hat where hat.isMagical else {
throw ChangoSpellError.HatMissingOrNotMagical
}guard let familiar = familiar else { throw ChangoSpellError.NoFamiliar } if familiar is Toad { throw ChangoSpellError.FamiliarAlreadyAToad } guard hasSpellOfType(.PrestoChango) else { throw ChangoSpellError.SpellNotKnownToWitch } guard let name = familiar.name else { let reason = "Familiar doesn’t have a name." throw ChangoSpellError.SpellFailed(reason: reason) } return Toad(name: name) } rethrows:只有參數(shù)函數(shù)拋出錯(cuò)誤,自己才會(huì)拋出錯(cuò)誤
func doSomethingMagical(magicalOperation: () throws -> MagicalResult) rethrows -> MagicalResult {
return try magicalOperation()
}
-
調(diào)用方法,處理錯(cuò)誤
func handleSpellError(error: ChangoSpellError) {
let prefix = "Spell Failed."
switch error {
case .HatMissingOrNotMagical:
print("(prefix) Did you forget your hat, or does it need its batteries charged?")case .FamiliarAlreadyAToad: print("\(prefix) Why are you trying to change a Toad into a Toad?") default: print(prefix) } } func exampleOne() { print("") // Add an empty line in the debug area // 1 let salem = Cat(name: "Salem Saberhagen") salem.speak() // 2 let witchOne = Witch(name: "Sabrina", familiar: salem) do { // 3 try witchOne.turnFamiliarIntoToad() } // 4 catch let error as ChangoSpellError { handleSpellError(error) } // 5 catch { print("Something went wrong, are you feeling OK?") } } exampleOne()
-
catch:模式匹配,類似switch,必須包含所有情況 -
try:正常情況;try?:將錯(cuò)誤轉(zhuǎn)換成nil;try!:保證不會(huì)有錯(cuò)誤,如果有,出現(xiàn)崩潰。
-
defer:棧結(jié)構(gòu),先進(jìn)后出。
func speak() {
defer {
print("cackles")
}defer { print("*screeches*") } print("Hello my pretties.") } speak()
三、推薦做法
- 確保錯(cuò)誤命名清晰
- 只有一個(gè)錯(cuò)誤時(shí)使用nil
- 超過(guò)一個(gè)錯(cuò)誤時(shí)使用自定義錯(cuò)誤
- 不要讓錯(cuò)誤傳遞太遠(yuǎn)