当前位置: 首页 >服务端 > Swift

Swift

Swift 对 Error Handling详解

苹果官方文档解释

跟其它语言一样,Swift的异常处理是在程序抛出异常后的处理逻辑。 Swift提供了一流的异常抛出、捕获和处理的能力。跟Java语言类似, Swift的异常并不是真正的程序崩溃, 而是程序运行的一个逻辑分支;Swift和Java捕获异常的时序也是一样的。当Swift运行时抛出异常后并没有被处理, 那么程序就会崩溃。

在Swift语言中使用Error表示异常, 作用同Java的Exception类或Object-C的NSError类。 苹果建议使用枚举作为异常类型(为什么不推荐用类或者结构体?答案是枚举数据类型本身就是分成若干种情况,很适合做逻辑分支判断条件)。

enum VendingMathineError: Error {case invalidSelectioncase insufficientFunds(coinsNeed: Int)case outOfStack}

上面声明了枚举类型VendingMathineError,继承于Error。 注意Swift的所有异常类型都继承于Error, 就像Java所有异常类都继承于Exception一样。

类似于Java处理异常的try/catch/finally, Swift提供了try、try?、try!、catch、throw、throws关键字处理异常逻辑,用法跟Java也很像。

 

如何声明一个可能抛出异常的函数?  在函数参数括号后面添加throws关键字, 跟Java语法有点像;区别是Swift的throws后面不用跟着异常类、而Java的throws后面要有异常类名称。 你只要告诉Swift这个函数可能抛出异常就够了,不需要说明到底是哪种异常,函数体内可以抛出任意类型的异常(肯定是继承于Error)。

func canThrowErrors() throws -> String

 

func canThrowErrors(type: Int) throws -> String? {//函数体写成switch/case更好一些if type == 1 {throw VendingMathineError.invalidSelection}if type == 2 {throw VendingMathineError.outOfStack}if type == 3 {throw VendingMathineError.insufficientFunds(coinsNeed: 100)}retu "success"}

 

上面测试代码是为了测试抛异常逻辑, 函数体写成switch/case更好一些。 从canThrowErrors函数看出,当参数为1、2或3时会抛异常, 语法是throw ... 且程序会跳出函数体,语法同Java。

 

Swift提供了一种类似于Java try/catch的语法, 是do(函数体内必须有try且该语句可能抛出异常)、catch。

 

 

do {try expressionstatements} catch patte 1 {statements} catch patte 2 where condition {statements}

 

注意:如果try语句抛出异常则会跳出do代码块,并按顺序逐个catch,当一个catch捕获成功后,后面的catch不再执行。

 

do {var data = try canThrowErrors(type: 3)//执行这个函数 这个函数可能抛出异常print("after execute canThrowErrors")if data != nil {print("Error test data:\(data)")}} catch VendingMathineError.outOfStack {print("outOfStack")} catch VendingMathineError.invalidSelection {print("invalidSelection")} catch {  //类似于Java的catch(Exception ex)print("Error")}

 

输出:Error

 

 

 

try canThrowsErrors(type: 3)会抛出VendingMathineError.isSufficientFunds(coinsNeed:100),不属于前2个catch类型, 而最后一个catch是捕获所有异常, 所有会执行其函数体。

      是不是感觉少了点什么? 对, 少了个类似于Java的finally,后面会介绍。 

      下面再介绍一下try?和try!的用法。

let x = try? someThrowingFunction()//与下面的相同let y: Int? do{y = try someThrowingFunction()}catch {y = nil}

 

try?后面的语句可能会抛出异常, 如果抛出异常则赋值nil给左侧;如果没抛出异常则将返回值赋给左侧;

try!取消异常捕获逻辑,语法有点任性,相当于裸奔, 明知可能抛出异常,但自信这段代码不会抛异常。 try!是try?的补充。你确定后面语句不会抛出异常,但真的抛出异常后程序会崩溃。不建议使用try!,有使用场景推荐使用try?

 

let tmpX = try? canThrowErrors(type: 1)  //如果抛出异常程序正常运行并赋值nil给左侧, 如果没抛异常则将返回值赋给左侧//let tmpY = try! canThrowErrors(type: 2)  //你很确定不会抛出异常时这样用,但如果运行时抛异常会导致程序崩溃

 

 

Swift使用defer关键字作用同Java的finally, 即使代码块内有break、continue、retu或者抛异常,在退出代码块后仍然会执行defer代码块

下面代码只是为了测试,验证函数体内抛出异常时的执行时序, 语法逻辑跟finally一模一样。

func testDefer(_ param: Int) throws -> String {print("testDefer begin")
defer {//抛出异常就执行defer 为抛出异常就最后执行deferprint("testDefer exit")}

// do something...
if param == 1 {throw VendingMathineError.invalidSelection}print("testDefer end")retu "testDefer retu"}//调用函数 该函数抛出异常tmpZ = nillet tmpZ = try? testDefer(1)

 

 

 

 

 输出:testDefer begintestDefer exit

 

 

没有 defer 抛出异常的执行逻辑

func testDeferNormal() {print("testDefer begin")defer {print("testDefer exit")}print("testDefer end")}testDeferNormal()

 

作者:俊华的博客
来源链接:https://www.cnblogs.com/junhuawang/p/6231084.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaclub.cn/server/113116.html

标签:异常处理
分享给朋友:

“Swift” 的相关文章

[C#]richtextbox实现拖放 2022年05月17日 20:25:47
[C++]VC自定义发IP包例子 2022年05月17日 20:41:27
Python 树表查找 2022年05月20日 21:28:27
视图的概念以及使用视图的好处 2022年05月21日 11:37:16
速看,三分钟带你了解IP协议! 2022年05月21日 22:21:46
Dart微基准测试第一部分 2022年05月23日 20:48:42
Web中的积累:外观模式 Facade 2022年05月29日 23:23:32