Swift3.0 对异常错误的处理

在OC中,单元测试时我们会使用断言,断言中条件满足时会产生异常,并打印出相应的断言错误。而在Swift对异常的处理和抛出也可以像其他语言一样处理。

//简单的异常使用枚举定义,但是枚举要继承Error协议,这里写两个异常, 没油, 超重
enum CarError: Error{
case lackOil
case overload
}
//定义汽车是否能驾驶
enum Driver {
case start//能否启动
case loading//能否载重
}
//货车类,两个属性,
//最少的油量,少于10%货车就不能启动。
//最大载重量,大于2000就不能工作
class  Car {
var minOil: Double = 0.1
var maxCargo: Double = 2000.0// kg
//throws 表示该方法会出现异常,不然不能被放在do里面
func drivering(driver: Driver)throws {//开车
    switch driver {
    case .start:
        //guard else 语句类似于if else 语句,   guard 后面的条件通过执行后面的语句,  不通过执行 else 里面的语句
        guard self.minOil > 1.0 else {
            throw CarError.lackOil //  抛出异常  返回上一调用方法,在catch里面找异常处理
        }
        print("the car begin move")
    case .loading:
        guard  self.maxCargo < 2000 else {
            throw CarError.overload
        }
        print("the car begin working")
    }
}

//现在我们写一个处理异常的方法,
func workingCar(car: Car)throws {
    //defer 关键字是在这个方法调用结束后一定会调用的方法。也是最后走的方法
    defer {
        print(" always run")
    }
    // do catch  在do闭包里面执行会抛出异常的代码,在catch 分支里面匹配异常处理异常, 在do 里面的调用都是throws 标记后的方法,意思是这个方法可能会出现异常
    // try! 使用try!  是我们确定这个调用不会发生异常 如果有异常,就会崩溃。一般不这么用
    //try 使用try 表示调用的方法会出现异常, 还有 try?调用了一个会出现异常的方法,并且结果转换为一个Optional, 异常返回nil
    
    do {
        //下面的调用是只要上一个出现异常,就不会继续调用下面的方法哦
        try car.drivering(driver: .loading)
        try car.drivering(driver: .start)
    } catch let CarError.lackOil {
        //对异常的处理
        print("  lack of oil ")
    } catch let CarError.overload {
        print("   overLoad ")
    }
}

//最后我们调用一下
let car = Car.init(oil: 0.5, cargo: 3000)
do {
try workingCar(car: car)
} catch  {
}

就会打印:
the car begin move
** overLoad **
** will will**

//再调用一下
let car = Car.init(oil: 0.05, cargo: 1500)
do {
try workingCar(car: car)
} catch  {
}

打印:
** lack of oil**
** will will**
因为缺油所以再抛出油量不够的异常后,后面的是否超重方法不在执行,但是will will 依然会执行
其实OC里面的异常处理我机会没有主动处理过,实在是难理解,一般都直接打印一下就不管了,并且一般看见error传个nil。如果你想看关于OC的异常处理,可以看这个NSError:http://nshipster.com/nserror/

推荐阅读更多精彩内容