Swift专题讲解十八——异常处理 原

Swift专题讲解十八——异常处理

一、异常的抛出与传递

        代码的运行很多时候并不会完全按照程序员的设想进行,编写代码时进行可控的异常处理机制是十分必要的。通常,对于一个特定的操作,程序员可以定义一个继承自ErrorType的枚举来进行异常类型的描述,使用throw关键字来进行异常的抛出,示例代码如下:

//定义一个自定义的错误类型
enum MyError:ErrorType {
    case DesTroyError
    case NormalError
    case SimpleError
}
//进行异常的抛出
throw MyError.NormalError

函数可以进行错误的传递,需要使用throws关键字来声明这个函数可能会抛出错误,如果不如此声明,则函数内部抛出的错误只能在函数内部解决,throws关键字标记的函数内部抛出的错误会被传递到调用函数的地方,开发者可以在调用函数的地方捕获到错误描述来做相应处理,示例如下:

func MyFunc()throws ->  Void {
    throw MyError.NormalError
}

对于可能抛出异常的函数调用,开发者要么在调用函数的地方捕获处理这些异常,要么使用try关键字将异常继续抛出去,等待下一层捕获者处理。异常的处理后面会介绍,继续抛出异常示例如下:

try MyFunc()

二、异常的处理

        除了将错误继续向上抛出之外,Swift还提供了3种处理异常的方式。

1.使用do-catch语句来捕获异常

        开发者可以使用do-catch语句来捕获异常,通过异常类型的判断来分别做处理,示例代码如下:

do{
   try MyFunc()
}catch MyError.DesTroyError{//将打印error1
    print("error1")
}catch MyError.NormalError{
     print("error2")
}catch MyError.SimpleError{
     print("error3")
}catch{//如果上面所有的catch都没有捕获 会走这个异常捕获判断
    print("all")
}

2.将异常映射为Optional值

        处理异常抛出的第2中方式是使用try?将异常映射为Optional值,可以简单理解为,对一个可能抛出异常的函数的调用,如果有异常抛出,则返回值为nil,如果没有,则函数顺利执行,返回值为其原返回值,示例如下:

//将返回nil
try? MyFunc()

注意:返回值为Void并非为nil,结合if-let语句可以编写十分飘逸的代码,示例如下:

if let _=try?MyFunc() {
    print("success")
}else{
    print("fail")
}

3.终止异常传递

        有时候开发者可以保证一个可能抛出异常的函数绝对不会抛出异常,这时开发者可以使用try!的方式来终止异常的传递,但是这样做有一定风险,如果这个函数真的抛出了异常,则会产生运行时错误。示例如下:

try! MyFunc()

三、延时执行语句

        对于某些释放资源类的操作,开发者总是希望其离开当前代码块时被执行,然后一个复杂流程结构可能会因异常抛出,return,break这些方式被终止,因此,Swift中提供了defer语句来进行延时执行一些操作,defer中的语句总是会在当前代码块将要结束时才执行,无论它是以哪种方式结束的,示例如下:

//执行此函数将打印
/*
 Care
 finish
 */
func MyFunc()throws ->  Void {
    
    defer{
        print("finish")
    }
    print("Care")
    throw MyError.DesTroyError
    
}

专注技术,热爱生活,交流技术,也做朋友。 ——珲少

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

转--Golang语言语法汇总

最近看了看GoLang,把Go语言的语法总结了一下,做个快速参考 数据类型 ---- var varName type,var var1,var2… type,...

35716
来自专栏宏伦工作室

全栈 - 4 Python 先学会基本语法

2687
来自专栏闪电gogogo的专栏

Python入门学习(二)

1 字典 1.1 字典的创建和访问 字典不同于前述的序列类型,它是一种映射类型。它的引入是为了简化定义索引值和元素值存在特定关系的定义和访问问题。 字典的定义形...

3168
来自专栏抠抠空间

细数Python中的数据类型以及他们的方法

一、数据类型的种类及主要功能 1、数字类型   数字类型主要是用来计算,它分为整数类型int和浮点类型float 2、布尔类型   布尔类型主要是用于判断,它分...

3385
来自专栏noteless

[四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式

前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明

1882
来自专栏Golang语言社区

Go语言语法汇总

最近看了看GoLang,把Go语言的语法总结了一下,做个快速参考 数据类型 ---- var varName type,var var1,var2… type,...

4328
来自专栏我爱编程

Python DEBUG

>>> l = [3] >>> l() Traceback (most recent call last): File "<pyshell#77>", li...

2984
来自专栏小古哥的博客园

读书笔记《PHP与MySQL程序设计》一

第1章 PHP概述 1.1  历史(PHP4、PHP5、PHP5.3、PHP6[未发布]) 1.2 一般语言特性(实用性、强大功能、可选择性、成本[开源]) 第...

4096
来自专栏海天一树

小朋友学C++(17):析构函数

析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后” ...

29510
来自专栏猿人谷

malloc和new有什么区别

malloc和new有以下不同: new、delete是操作符,可以重载,只能在c++中使用。 malloc、free是函数,可以覆盖,c、c++中都可以使用。...

18810

扫码关注云+社区

领取腾讯云代金券