错误处理 Error Handling
8.6 defer语法可以让代码更简洁 Clearing Up Using defer
本小节内容比较简单,主要延续之前的文件的有效性查询的Demo来引出defer语法,并介绍一些相关特性
引出defer关键字: 一般在可能抛出异常的方法都会使用 try/finally结构。无论最后是否有抛出异常都会走finally流程。 这个时候我们就可以使用defer语法让代码变得更灵活
。
defer关键字的作用:实际是一个闭包
,在当前声明的作用域结束时执行
。
defer在文件读写中的使用.
func contents(ofFile ?lename: String) throws -> String {
let file = open("test.txt", O_RDONLY)
defer { close(file) }
let contents = try process(file: file)
return contents
}
注1:在上面的demo中,如果不用defer关键字 当出现异常
,直接就try 提前结束了. 导致当前的文件流没有执行close方法。这个在以后的数据库操作中可算是一个重大bug
。
注2: defer要写在reture 前面
。 虽然它的执行上在return后。 你写在return后面,代码编译 return后的代码看都不看。这个时候你写defer实际上没啥用。
标准库中对defer的使用
下面会写出```Enumeratedlterator```协议中```next()```方法的代码实现。
##### 使用场景:增加计数器的值而且需要返回没有增加值之前的值。
struct EnumeratedIterator<Base: IteratorProtocol>: IteratorProtocol, Sequence {
internal var _base: Base
internal var _count: Int ...
func next() -> Element? {
guard let b = _base.next() else { return nil }
defer { _count += 1 }
return (offset: _count, element: b)
}
}
多defer方法多使用注意
写一个操作数据库的Demo来讲讲
guard let database = openDatabase(...) else { return }
defer { closeDatabase(database) }
guard let connection = openConnection(database) else { return }
defer { closeConnection(connection) }
guard let result = runQuery(connection, ...) else { return }
类似于压栈操作
,前面的后执行,后面的先执行。
上面的demo中的顺序也是在执行完数据库查询之后先```关闭链接```,再去```关闭数据库```。
over~
网友评论