Swift异常处理的try?与try!
首先要明白抛出异常后异常的运动:异常被抛出后,中断整个处理,异常不断向外层(范围)传递,直到遇到catch代码块群,会与catch代码块的条件进行匹配,匹配符合则进入此代码块处理。如果遇到没有条件的catch{}那么直接在这个代码里处理。如果抛出的异常一直到最外层仍没有被catch{}处理,那么程序会卡住(后面的处理全部中断)
enum numTest: Int, Error {
case _0, _1, _2, _3
case nothing = 999
}
func errorTest(by num: Int) throws -> String {
switch num {
case 0:
throw numTest._0
case 1:
throw numTest._1
case 2:
throw numTest._2
case 3:
throw numTest._3
case 10:
throw numTest.nothing
default:
return "OK" + " \(num)"
}
}
我们用这一段代码来测试
print("即将开始测试")
try errorTest(by: 0)
print("测试结束")
print("因为异常没有被捕捉,所以这两句话不会运行")
运行结果如下:
即将开始测试
换言之,如果我们抛出了异常,那就必须进行处理,不想处理?那么就加个空的无条件的catch{},为了方便观测效果,我们在catch里输出测试中
print("即将开始测试")
do {
try errorTest(by:
0)
}catch {
print("---测试中---")
}
print("测试结束")
print("因为异常被捕捉,所以这两句话会运行")
运行结果如下:
即将开始测试
---测试中---
测试结束
因为异常被捕捉,所以这两句话会运行
由以上测试可知,抛出的异常必须被处理,不然异常会导致程序中断,出现假死现象
可是,每次都要加上do-catch这一长串,无论是从代码的可读性还是写代码的角度都是非常不好的。这里,try?与try!就可以大显身手了
其实到这里,相信大家也很清楚try?和try!的作用了。
没错,try?是一个可选绑定,当后面运行的可以抛出异常的函数没有抛出异常,则直接运行。当抛出异常,则跳过此函数。既然是可选绑定,那么如果用在条件里,如果没抛出异常,那么返回的值带入声明量(void返回的是void的空值,不是nil),如果抛出,可选绑定判定为false,和普通的可选绑定一样
先看下面这个例子
print("即将开始测试")
try?
errorTest(by:
0)
print("测试结束")
运行结果如下:
即将开始测试
测试结束
把try?改成try
print("即将开始测试")
try errorTest(by:
0)
print("测试结束")
运行结果如下:
即将开始测试
带入条件
for i in
0 ..< 10
where i == 3 ||
i == 5 {
//for ] {
print("即将开始测试")
if let myTest =
try? errorTest(by: i)
{
print("测试中,",
terminator: "")
print("没有抛出异常,
测试值\(myTest)")
}else {
print("测试中,",
terminator: "")
print("抛出异常")
}
print("测试结束")
print("-----------")
}
运行结果如下:
即将开始测试
测试中,抛出异常
测试结束
-----------
即将开始测试
测试中,没有抛出异常,
测试值OK 5
测试结束
-----------
最后再来看看try!,这个很明显了,就是默认不会抛出异常,直接运行,如果抛出运行在编译出错
print("即将开始测试")
print("正常值:
", try!
errorTest(by:
6))
print("测试结束")
运行结果如下:
即将开始测试
正常值: OK
6
测试结束
最后总结一下,try?和try!主要用在对异常抛出函数进行不需要捕捉异常的处理。当然,一般不建议用try!,后期容易出问题
Swift异常处理的try?与try!的更多相关文章
- Swift异常处理:throw和rethrow
Swift异常处理体现了函数式语言的特性.因此我们能够传一个会抛出异常的函数闭包(高阶函数)作为參数传到还有一个函数中(父函数),父函数能够在子函数抛出异常时直接向上抛出异常,这时用rethrowke ...
- iOS - Swift 异常处理
前言 在 Swift 1.0 时代是没有异常处理和抛出机制的,如果要处理异常,要么使用 if else 语句或 switch 语句判断处理,要么使用闭包形式的回调函数处理,再要么就使用 NSError ...
- Swift # 异常处理
面向轨道编程 - Swift 中的异常处理 问题 在开发过程中,异常处理算是比较常见的问题了. 举一个比较常见的例子:用户修改注册的邮箱,大概分为以下几个步骤: 接收到一个用户的请求:我要修改邮箱地址 ...
- Swift异常处理
在Swift里,抛出的异常必须继承Error这个协议.那么这个协议是什么呢? 按住command再点击Error我们可以看到, public protocol Error { } extension ...
- swift 中异常的处理方法
swift 中什么时候需要处理异常,在调用系统某个方法的时,该方法最后有一个throws 说明该方法会抛出异常,如果一个方法抛出异常,那么需要对该异常进行处理 swift 异常处理提供了三种方法 方式 ...
- Swift try try! try?使用和区别
Swift try try! try?使用和区别 一.异常处理try catch的使用 1. swift异常处理 历史由来 Swift1.0版本 Cocoa Touch 的 NSError ,Swif ...
- Swift 使用 日常笔记
//------------------- var totalPrice: Int = { willSet(newTotalPrice) { //参数使用new+变量名且变量名首地址大写 printl ...
- Mac终端使用swift REPL异常处理方法
Mac终端使用swift REPL异常处理方法 终端使用swift命令出现 warning: Swift error in module libmarisa.dylibDebug info from ...
- Swift 2.0 异常处理
转自:http://www.jianshu.com/p/96a7db3fde00 WWDC 2015 宣布了新的 Swift 2.0. 这次重大更新给 Swift 提供了新的异常处理方法.这篇文章会主 ...
随机推荐
- Linux温习(三)Linux文件和文件夹管理
关于Linux文件夹的几个常见概念 路径 对文件位置信息的描写叙述机制.是指从树型文件夹中的某个文件夹层次到其内某个文件的一条通路.分为相对路径和绝对路径: 工作文件夹 登入系统后.用户始终处于某个文 ...
- 线程特定数据TSD总结
一线程的本质 二线程模型的引入 三线程特定数据 四关键函数说明 五刨根问底啥原理 六私有数据使用演示样例 七參考文档 一.线程的本质 Linux线程又称轻量进程(LWP),也就说线程本质是用进程之间共 ...
- Android——坐标系及转化
一.坐标系 Android应用层坐标系原点在左上角,坐标范围(0,0)——(width,height). Android底层坐标系原点在屏幕中央,坐标范围(-1000,,1000)——(1000,10 ...
- 时间格式 2016-08-15T16:00:00.000Z
我修改的时间是2016-08-16(转换成Date后默认为2016-08-16 00:00:00),而我得到的时间却是2016-08-15T16:00:00.000Z 联想到我们当前的时区是+8区 ...
- 三种方法打印 main函数的返回地址的值(old EIP)(用途,你懂得!)
这里能够简单的改动随意函数的返回地址.能够做到自己定义EIP的指向,就可以运行当前进程空间的随意指令,这里仅仅是让大家更清楚栈帧结构,没有涉及跨进程的inline HOOK 等,后面会陆续讲下读取随意 ...
- mysql创建 存储过程 并通过java程序调用该存储过程
create table users_ning(id primary key auto_increment,pwd int); insert into users_ning values(id,123 ...
- ermissions on /usr/local/mongodb/conf/keyFile are too open
ermissions on /usr/local/mongodb/conf/keyFile are too open > rs.initiate(cfg); { "ok" : ...
- 正则表达式pattern的匹配格式
0> 匹配 -------------------------------------------------------------------------------- (pattern) ...
- C# 自定义控件及引用自动义控件
1.http://www.cnblogs.com/hjxzjp/p/7823292.html 优先考虑从现有的控件中进行派生,并添加所需要的功能. 在解决方案资源管理器窗口中设置:引用----&g ...
- Eclipse设置java环境
通用JRE环境设置: Window->Preferences->Java->Installed JREs 设置jre路径,如C:\Program Files\Java\jre1.8. ...