错误处理 Error Handling
8.5 错误和函数参数 Errors and Function Parameters
本小节主要对下面两个demo的统一抽象封装引出来的一些思路。
1.查看某一系列文件的有效性
2.看一个数字数组中所有数字是不是都不是质数
因为检查是不是质数不会报错,而检查文件可能会throws异常,从而引出rethrow
关键字。
Demo1.一系列文件有效性的检查
检查一个文件的有效性checkFile方法应该有三种情况,有效
,无效
,检查出错
Demo中 用一个for循环确认每一个文件的有效性,遇到无效文件或者检查出错都会提前退出循环
。
///检查文件有效性的方法
func checkFile(filename: String) throws -> Bool
func checkAllFiles(filenames: [String]) throws -> Bool {
for filename in filenames {
guard try checkFile(filename: filename) else { return false } }
return true
}
Demo2.检查一个数字数组中是否含有质数 和Demo1相似,但不会throws异常
func checkPrimes(_ numbers: [Int]) -> Bool {
for number in numbers {
guard number.isPrime else { return false }
}
return true
}
checkPrimes([2,3,7,17]) // true
checkPrimes([2,3,4,5]) // false
作为一个优秀的高级开发工程师
(码农。。) 肯定会对这两个高度相似的方法是做一个完美的封装
我们暂定封装的方法方法名叫all()
, all方法的参数是一个判断条件是否满足的函数
。
extension Sequence {
/// Returns `true` iff all elements satisfy the predicate
func all(condition: (Iterator.Element) -> Bool) -> Bool {
for element in self {
guard condition(element) else { return false }
}
return true
}
}
下面我们开始享受我们封装完之后的战果了。
查看是否有质数 一行代码搞定。
func checkPrimes2(_ numbers: [Int]) -> Bool {
return numbers.all { $0.isPrime }
}
Rethrows 关键字
下面问题就来了,查看有限文件时可能会异常。这个封装不好使啊~
这个时候我们可以使用rethrows关键字
rethrows关键字作用
: 告诉编译器,这个函数只会在它的参数函数抛错时抛错
编译器可以避免我们一定要用try调用。
extension Sequence {
func all(condition: (Iterator.Element) throws -> Bool) rethrows
-> Bool {
for element in self {
guard try condition(element) else { return false }
}
return true
}
}
上面检查质数的Demo不受影响,而且检查文件有效性就可以像下面这样写了
///有try了
func checkAllFiles(filenames: [String]) throws -> Bool {
return try filenames.all(condition: checkFile)
}
知识点:标准库中序列和集合几乎所有可以接收函数做参数的函数
都被标记成rethrows了。 这样做就很稳了~
over~
网友评论