swift2.1_Language Guide_Error Handling

2024-03-01 10:08

本文主要是介绍swift2.1_Language Guide_Error Handling,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这部分是新增的,加在第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


这篇关于swift2.1_Language Guide_Error Handling的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/762074

相关文章

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

论文翻译:ICLR-2024 PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS

PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS https://openreview.net/forum?id=KS8mIvetg2 验证测试集污染在黑盒语言模型中 文章目录 验证测试集污染在黑盒语言模型中摘要1 引言 摘要 大型语言模型是在大量互联网数据上训练的,这引发了人们的担忧和猜测,即它们可能已

UML- 统一建模语言(Unified Modeling Language)创建项目的序列图及类图

陈科肇 ============= 1.主要模型 在UML系统开发中有三个主要的模型: 功能模型:从用户的角度展示系统的功能,包括用例图。 对象模型:采用对象、属性、操作、关联等概念展示系统的结构和基础,包括类图、对象图、包图。 动态模型:展现系统的内部行为。 包括序列图、活动图、状态图。 因为要创建个人空间项目并不是一个很大的项目,我这里只须关注两种图的创建就可以了,而在开始创建UML图

速通GPT-3:Language Models are Few-Shot Learners全文解读

文章目录 论文实验总览1. 任务设置与测试策略2. 任务类别3. 关键实验结果4. 数据污染与实验局限性5. 总结与贡献 Abstract1. 概括2. 具体分析3. 摘要全文翻译4. 为什么不需要梯度更新或微调⭐ Introduction1. 概括2. 具体分析3. 进一步分析 Approach1. 概括2. 具体分析3. 进一步分析 Results1. 概括2. 具体分析2.1 语言模型

编译linux内核出现 arm-eabi-gcc: error: : No such file or directory

external/e2fsprogs/lib/ext2fs/tdb.c:673:29: warning: comparison between : In function 'max2165_set_params': -。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。 。。。。。。。。 host asm: libdvm <= dalvik/vm/mterp/out/Inte

收藏:解决 pip install 出现 error: subprocess-exited-with-error 错误的方法

在使用 pip 安装 Python 包时,有时候会遇到 error: subprocess-exited-with-error 错误。这种错误通常是由于 setuptools 版本问题引起的。本文将介绍如何解决这一问题 当你使用 pip install 安装某个 Python 包时,如果 setuptools 版本过高或过低,可能会导致安装过程出错,并出现类似以下错误信息:error: subpr

Nn criterions don’t compute the gradient w.r.t. targets error「pytorch」 (debug笔记)

Nn criterions don’t compute the gradient w.r.t. targets error「pytorch」 ##一、 缘由及解决方法 把这个pytorch-ddpg|github搬到jupyter notebook上运行时,出现错误Nn criterions don’t compute the gradient w.r.t. targets error。注:我用

src/pyaudio/device_api.c:9:10: fatal error: portaudio.h: 没有那个文件或目录

(venv) shgbitai@shgbitai-C9X299-PGF:~/pythonworkspace/ai-accompany$ pip install pyaudio sounddeviceCollecting pyaudioDownloading PyAudio-0.2.14.tar.gz (47 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ERROR 2003 (HY000): Can't connect to MySQL server on (10061)

在linux系统上装了一个mysql-5.5,启动后本机都是可以访问的,操作都正常,同时建了一个%的用户(支持远程访问), root@debian:/# mysql -u loongson -pEnter password: Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id

pip install pyaudio sounddevice error: externally-managed-environment

shgbitai@shgbitai-C9X299-PGF:~/pythonworkspace/ai-accompany$ pip install pyaudio sounddeviceerror: externally-managed-environment× This environment is externally managed╰─> To install Python package