一、使用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 语句
init?(words: String) {
guard let incantation = MagicWords(rawValue: words) else {
return nil
}
self.magicWords = incantation
}
二、自定义错误处理
do-try-catch 机制的关键字:
throws
do
catch
try
defer
ErrorType
- 定义错误
enum ChangoSpellError: ErrorType {
case HatMissingOrNotMagical
case NoFamiliar
case FamiliarAlreadyAToad
case SpellFailed(reason: String)
case SpellNotKnownToWitch
}
- 遵守
ErrorType
协议 - 通过关联值绑定具体的错误原因
- 定义方法
方法声明(或协议方法声明)添加
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.
}-
方法实现抛出错误
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
:只有参数函数抛出错误,自己才会抛出错误
func doSomethingMagical(magicalOperation: () throws -> MagicalResult) rethrows -> MagicalResult {
return try magicalOperation()
}
-
调用方法,处理错误
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?
:将错误转换成nil
;try!
:保证不会有错误,如果有,出现崩溃。
-
defer
:栈结构,先进后出。
func speak() {
defer {
print("cackles")
}defer { print("*screeches*") } print("Hello my pretties.") } speak()
三、推荐做法
- 确保错误命名清晰
- 只有一个错误时使用nil
- 超过一个错误时使用自定义错误
- 不要让错误传递太远