错误处理

错误处理是响应错误以及从错误中返回的过程。swift提供第一类错误支持,包括在运行时抛出,捕获,传送和控制可回收错误。

一些函数和方法不能总保证能够执行所有代码或产生有用的输出。可空类型用来表示值可能为空,但是当函数执行失败的事后,可空通常可以用来确定执行失败的原因,因此代码可以正确地响应失败。在Swift中,这叫做抛出函数或者抛出方法。

错误的表示

在Swift中,错误用符合ErrorType协议的值表示。 Swift枚举特别适合把一系列相关的错误组合在一起,同时可以把一些相关的值和错误关联在一起。因此编译器会为实现ErrorType协议的Swift枚举类型自动实现相应合成。

// 模拟自动售卖机的错误情况
enum VendingMachineError: ErrorType {
// 商品不存在时
case InvalidSelection
// 投入的钱不够时
case InsufficientFunds(required: Double)
// 商品卖完了
case OutOfStock
}

错误抛出 通过在函数或方法声明的参数后面加上throws关键字,表明这个函数或方法可以抛出错误。如果指定一个返回值,可以把throws关键字放在返回箭头(->)的前面。

func canThrowError() throw -> String

func cannotThrowError() -> String

当调用一个抛出函数的时候,在调用前面加上try。这个关键字表明函数可以抛出错误。

let favoriteSnacks = [
"Alice": "Chips",
"Bob": "Licorice",
"Eve": "Pretzels",
] func buyFavoriteSnack(person: String) throws {
let snackName = favoriteSnacks[person] ?? "Candy Bar"
try vend(itemName: snackName)
}

捕捉和处理错误

使用do-catch语句来就捕获和处理错误

do {
try vend(itemName: "Candy Bar")
// 如果vend会抛出错误的话,会传递到catch中
// 可以在catch里处理发生错误后应做的事情,不会造成运行时错误
} catch VendingMachineError.InvalidSelection {
print("Invalid Selection")
} catch VendingMachineError.InsufficientFunds(let amountRequired) {
print("Insufficient funds. Please insert an additional $\(amountRequired).")
} catch VendingMachineError.OutOfStock {
print("Out of Stock")
}
// Insufficient funds. Please insert an additional $0.25.

注意:Swift中的错误处理和其他语言中的异常处理很像,使用了trycatchthrow关键字。但是和这些语言——包括Objective-C——不同的是,Swift不会展开调用堆栈,那会带来很大的性能损耗。因此,在Swift中throw语句的性能可以做到几乎和return语句一样。

禁止错误传播

在运行时,有几种情况抛出函数事实上是不会抛出错误的。在这几种情况下,你可以用forced-try表达式来调用抛出函数或方法,即使用try!来代替try

通过try!来调用抛出函数或方法禁止了错误传送,并且把调用包装在运行时断言,这样就不会抛出错误。如果错误真的抛出了,会触发运行时错误。

enum CustomError: ErrorType {
case SomeError
} func willOnlyThrowIfTrue(value: Bool) throws {
if value { throw CustomError.SomeError }
} do {
try willOnlyThrowIfTrue(true)
} catch {
print("Error")
} try! willOnlyThrowIfTrue(true) // 运行时错误

收尾操作

使用defer语句来在执行一系列的语句。这样不管有没有错误发生,都可以执行一些必要的收尾操作。包括关闭打开的文件描述符以及释放所有手动分配的内存。

defer语句把执行推迟到退出当前域的时候。defer语句包括defer关键字以及后面要执行的语句。被推迟的语句可能不包含任何将执行流程转移到外部的代码,比如break或者return语句,或者通过抛出一个错误。被推迟的操作的执行的顺序和他们定义的顺序相反,也就是说,在第一个defer语句中的代码在第二个defer语句中的代码之后执行。

func processFile(filename: String) throws {
if exists(filename) {
let file = open(filename)
defer {
close(file)
}
while let line = try file.readline() {
// 写文件
}
// defer中的close(file) 会在最后调用。不管有没有抛出错误
}
}

学习Swift -- 错误处理的更多相关文章

  1. ios -- 教你如何轻松学习Swift语法(三) 完结篇

    前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦.      一.自动引用计数   1.自动引用计数工作机制      1.1 swift和o ...

  2. ios -- 教你如何轻松学习Swift语法(二)

    前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦.      一.可选类型(重点内容)   1.什么是可选类型?        1.1在OC开 ...

  3. ios -- 教你如何轻松学习Swift语法(一)

    目前随着公司开发模式的变更,swift也显得越发重要,相对来说,swift语言更加简洁,严谨.但对于我来说,感觉swift细节的处理很繁琐,可能是还没适应的缘故吧.基本每写一句代码,都要对变量的数据类 ...

  4. Swift 错误记录

    最近几天开始学习Swift,作为一个从 OC 转到 Swift 的程序员,我一直以为很简单.但是现在学习一个星期之后,发现问题还是蛮多的! 最大的问题就是 太特么 不习惯了!!!!!!!!!! 好吧, ...

  5. 一步一步学习Swift之(一):关于swift与开发环境配置

    一.什么是Swift? 1.Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用. 2.Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制. 3.Sw ...

  6. 開始学习swift开发

    近期要開始学习swift开发了,接下来的日子,会记录学习swift的历程.

  7. 学习swift语言的快速入门教程推荐

    随着苹果产品越来越火爆,苹果新推出的swift必定将在很大程度上代替oc语言.学好swift语言,对于IOS工程师来讲,已经是一门必备技能. 有一些比较好的英文版教程,值得学习. 1. Swift T ...

  8. CAN总线学习总结——错误帧和错误状态

    CAN总线学习总结——错误帧和错误状态 标签: 数据 / 错误帧 / 错误状态 / CAN总线 / 总线协议 253 一.五种CAN总线可能发生的错误 1.CRC错误: 接收节点计算出的CRC校验值, ...

  9. 一步一步学习Swift之(二):好玩的工具playground与swfit基础语法

    playground好于在于能一边写代码一边看到输出的常量变量的值.不需要运行模拟器. 我们来试一下该工具的用法. 打开xcode6开发工具,选择Get started with a playgrou ...

随机推荐

  1. ASP.NET MVC提交到服务器的几种方法

    多年不搞WEB开发了,最近有个小活干干,记录一下学习的心得. 以下为几种脚本向服务器提交的方法: 1. $.ajax({ type: "GET", url: "/Test ...

  2. 第一个Xcode项目 - 代码修改布局约束

    第一行的选中效果已经有了,那第二行的选中效果怎么做呢?我这里选择改变布局约束来实现选中效果 [我有个用object-c做APP的同事他说,我觉得这个应该去获取色块的位置,然后赋给选中用的View,然后 ...

  3. android 69 SQLite数据库

    package com.itheima.sqlitedatabase; import java.sql.ResultSet; import android.content.Context; impor ...

  4. iOS-SQLite数据库使用介绍

    iOS-SQLite数据库使用介绍 SQLite是MySQL的简化版,更多的运用与移动设备或小型设备上.SQLite的优点是具有可移植性,它不需要服务器就能运行,同时,它也存在一些缺陷,首先,没有提供 ...

  5. spring注解:@PostConstruct和@PreDestroy

    关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 第二 ...

  6. wsdl自动生成Java代码,根据wsdl生成Java代码

    wsdl自动生成Java代码,根据wsdl生成Java代码 >>>>>>>>>>>>>>>>>&g ...

  7. HTML+CSS 整站 步骤

    文件夹管理: CSS JS img font html 根据设计图,划分区块 ,即页面布局 重置样式 ;padding:0;} 写main.css  注意:1 距离尽量使用偶数,避免奇数 2 在使用定 ...

  8. JS 时间格式化函数

    //时间格式化函数 Date.prototype.format = function (format) { var o = { "M+": this.getMonth() + 1, ...

  9. C++ 常见问题

    1:保证编译后方法名不被修改:  The: extern "C" { function declarations here in h file } will disable C++ ...

  10. Struts2单文件上传

    第一步:首先写个上传文件的页面(简单的一个form表单) <html> <head> <meta http-equiv="Content-Type" ...