swift2.1_Language Guide_Error Handling

原创 2015年11月20日 12:47:31

这部分是新增的,加在第18节


18Error Handling


异常处理是在你程序中响应和捕获异常的处理过程

 

一些处理并不保证总是成功执行或产生有用的输出。可选值可用来代表一个值是否存在,但当操作失败时,搞清楚什么原因导致失败并做相应处理往往很重要。

考虑一个例子,读取和处理磁盘上一个文件的数据。有多种原因可能导致失败,包括文件不存在,没有读取权限,或编码格式不匹配等。区分这些不同的情况需要程序捕获异常然后再提示用户。


NOTE

异常处理的处理方式不同于Cocoa和OC中得NSError的方式。参见Using Swift with Cocoa and Objective-C 中 Error Handling 


18.1Representing and Throwing Errors


表示和抛出异常

 

在swift中,异常用符合ErrorType协议的类型值表示。这个协议代表一个可以用作异常处理的类型


枚举类型可以很好的代表一组相关的异常情况,还可以有参数来增加额外的信息。比如:自动售卖机的错误信息可以类似如下:


enum VendingMachineError: ErrorType {

    case InvalidSelection

    case InsufficientFunds(coinsNeeded: Int)

    case OutOfStock

}


抛出异常说明有不正常的情况发生,正常流程无法继续进行。

用throw语句来抛出异常。比如,下面的代码抛出一个异常指明售货机还要你5个硬币


throw VendingMachineError.InsufficientFunds(coinsNeeded: 5)


18.2Handling Errors

有4种方法处理异常

1,抛出给外层处理

2,使用do-catch语句处理

3,用可选值处理

4,断言不会发生异常

这些后面会详细介绍


当一个函数抛出异常,他将改变程序的流程,所以在你的代码中定位可能出现异常的位置就很重要。为了定位异常位置,在调用函数,方法或初始化前使用try,try?,try!关键字。这些关键字后面会再进行描述。


NOTE

swift的异常处理类似一些其他的语言,使用try,catch和throw关键字。而不像另一些语言(包括Objective-C)。error handling in Swift does not involve unwinding the call stack, a process that can be computationally expensive. As such, the performance characteristics of a throw statement are comparable to those of a return statement.


18.2.1Propagating Errors Using Throwing Functions


为了说明一个函数,方法或构造函数可能抛出异常,在声明中的参数后面写上shrows关键字。标记有throws的函数称为throwing function。如果函数有返回值,那么throws写在返回值的箭头前面。


func canThrowErrors() throws -> String


func cannotThrowErrors() -> String


NOTE

只有throwing function可以抛出异常,nonthrowing function中的异常,必须在自己内部处理掉


下面的例子中VendingMachine得vend(itemNamed:)方法会抛出异常


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 var 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

        --item.count

        inventory[name] = item

        dispenseSnack(name)

    }

}


vend(itemName:)方法使用了guard语句,如果要求不能满足,则将提前退出并抛出异常。只有所有条件都满足时才能售货成功。

因为vend(itemNamed:)可能抛出异常,所以调用时必须处理,可以使用do-catch语句,try?或 try!, 或是继续往外抛出。

下面是继续往外抛的例子:


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)

}


因为vend(itemNamed:)方法会抛出异常,前面要加try


18.2.2Handling Errors Using Do-Catch


如果do中抛出异常,则将通过匹配catch来决定那段代码来处理异常

do {

    try expression

    statements

} catch pattern 1 {

    statements

} catch pattern 2 where condition {

    statements

}


pattern用来指明他可以处理哪些异常,如果一个catch没有pattern,那么他将可以处理所有的异常

catch分句不需要处理所有可能的异常。如果没有catch分句处理异常,异常会继续往外抛,但是异常总是需要被处理掉的。下面的代码处理了三个异常,其他的异常将继续外抛


var vendingMachine = VendingMachine()

vendingMachine.coinsDeposited = 8

do {

    try buyFavoriteSnack("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.")

}

// prints "Insufficient funds. Please insert an additional 2 coins."


18.2.3Converting Errors to Optional Values


可以使用try?把异常包装成一个可选值。如果有异常抛出,则可选值将为nil。下面的代码中,x和y的值将会是相等的


func someThrowingFunction() throws -> Int {

    // ...

}


let x = try? someThrowingFunction()


let y: Int?

do {

    y = try someThrowingFunction()

} catch {

    y = nil

}


如果有异常,则x和y的值为nil,如没有异常,则是函数的返回值。

使用try?可以使你能够更便捷的处理异常。

下面的例子用两种方式获取数据,如果都失败则返回nil


func fetchData() -> Data? {

    if let data = try? fetchDataFromDisk() { return data }

    if let data = try? fetchDataFromServer() { return data }

    return nil

}


18.2.4Disabling Error Propagation


有时你知道这些函数,方法在运行时并不会抛出异常。这时你可以使用try!来断言不会发生异常。假如实际上却发生异常了,将抛出运行时异常。

下例,函数导入图片资源,因为图片资源随应用打包,所以不会发生异常,这是你就可以try!

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


18.3Specifying Cleanup Actions


如果你想在执行流离开当前代码块前执行一部分代码,你可以使用defer语句块。

不管执行流以何种方式离开当前代码块,不管是异常,还是rutuen,或是break,defer语句块都能让你做必要的清理。

因此,你可以使用defer语句块来确保你在打开文件后有关掉它,你开辟的空间有释放他。


defer语句推迟语句内容到当前块结束时执行。defer内容不能有跳出语句,如break和return,也不能抛出异常。当有多个defer语句块时,将倒序执行。

func processFile(filename: String) throws {

    if exists(filename) {

        let file = open(filename)

        defer {

            close(file)

        }

        while let line = try file.readline() {

            // Work with the file.

        }

        // close(file) is called here, at the end of the scope.

    }

}


上面defer语句块,确保文件会被关闭


func test(){

    defer{

        print("11111")

    }

    defer{

        print("22222")

    }

    defer{

        print("33333")

    }

}


test()

//print 33333

//print 22222

//print 11111


Swift 错误处理(Error Handling)

错误处理是响应错误以及从错误中返回的过程。swift提供第一类错误支持,包括在运行时抛出,捕获,传送和控制可回收错误。 一些函数和方法不能总保证能够执行所有代码或产生有用的输出。可空类型用来表示值可...

对照Java学习Swift--错误处理(Error Handling)

简介在异常处理方面,Java跟Swift很相似,要么抛出异常,要么自己处理异常,但是语法有些不太一样。 抛出异常Java跟Swift都是用throws关键字,Java在小括号的后面,大括号的前面,Sw...

Swift错误处理(Error Handling)

错误处理是在程序中响应错误和处理错误恢复程序正常运行的过程。Swift提供了抛出、捕获、传播和操作可恢复的过程。有的操作不是每次都能执行成功的,而可选链是用来判断有没有值,但操作失败时,无法知道失败的...

Swift-错误处理(Error Handling)(十六)

前言错误处理Error Handling 是响应错误以及从错误中恢复的过程。Swift 提供了在运行时对可恢复错误抛出,捕获,传递和操作的高级支持。小节包含下面的知识点: 表示并抛出错误 处理错误 指...
  • xxh0307
  • xxh0307
  • 2016年05月30日 13:15
  • 2343

Swift学习——Language Guide 基础

The Basics Swift is a new programming language for iOS and OS X app development. Nonetheless, many p...

Swift 语言指南,Swift Language Guide,第2章基本运算符

第2章 基本运算符 运算符(operator)是用于检查、更改或组合值的特殊符号或短语。例如,加法运算符(+)求两个数字的加和(如let i = 1 + 2)。更复杂的例子包括逻辑与(logical...

Chapter9-3.Interrupt handling schemes 《ARM system developer's guide》

Interrupt Handling Schemes1.Nonnested Interrupt Handling2.Nested Interrupt Handler 进行一次context转换需要...

systematic error handling in c++

  • 2016年04月08日 12:11
  • 278KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:swift2.1_Language Guide_Error Handling
举报原因:
原因补充:

(最多只允许输入30个字)