Swift Error 处理

定义一个方法,获取两个数的除数,针对下面这段代码来进行Error的处理

    func divide(_ num1: Int, _ num2: Int) -> Int {
        num1 / num2
    }

当 num2 为 0 的时候,上面代码会发生运行时错误,导致程序崩溃
为解决这个问题,我们需要在代码中对 num2 == 0 单独做判断,然后抛出异常信息

    struct MyError: Error {
        var msg: String
    }
    
    func divide(_ num1: Int, _ num2: Int) throws -> Int {
        if num2 == 0 {
            throw MyError.init(msg: "除数不能为0")
        }
        return num1 / num2
    }

这样当调用 divide 这个方法的时候需要对有可能捕获到的异常信息进行处理,处理方式如下

1、通过 do-catch 捕捉 Error

        do {
            print(1)
            print(try divide(10, 0))
            print(2)
        } catch let error as MyError {
            print(3)
            print(error.msg)
        } catch {
            print("其它错误")
        }

        // 打印结果
        1
        3
        除数不能为0


do catch 必须对所有可能出现的错误结果进行罗列,不然会报错,所以在上面会有 catch 打印"其他错误", 如果不想对详细错误信息进行处理,也可以直接这样写

        do {
            print(try divide(10, 0))
        } catch {
            print("参数错误")
            // 在catch的作用域中自带一个error,可以直接打印
            print(error)
        }

2、不捕捉Error,在当前函数增加throws声明,Error将自动抛给上层函数,如果最顶层函数(main函数)依然没有捕捉Error,那么程序将终止

    func test() throws {
        print(try divide(10, 0))
    }

3、可以使用 try? try! 调用可能会抛出Error的函数,这样就不用去处理Error

        print(try? divide(10, 1))
        print(try? divide(10, 0))
        print(try! divide(10, 2))
        print(try! divide(10, 0))
        // 打印结果
        Optional(10)
        nil
        5
        崩溃

需要注意一下,使用try?得到的结果是可选类型
使用try!解包可能会导致崩溃,除非你确定除数不是0,否则不要用

4、assert(断言)

断言机制:不符合指定条件就抛出运行时错误,常用于调试(debug)阶段的条件判断

    func divide(_ v1: Int, _ v2: Int) -> Int {
        // 当条件为 false时,打印断言中的抛出的错误信息
        assert(v2 != 0, "除数不能为0")
        return v1 / v2
    }

默认情况下,Swift的断言只会在Debug模式下生效,Release模式下会忽略。可手动强制开启或者关闭,TARGETS---Building Settings---Other Swift Flags

  • -assert-config Release:Debug模式下强制关闭断言
  • -assert-config Debug:Release模式下强制开启断言


    assert@2x.png

5、fatalError

如果遇到严重问题,希望结束程序运行,可以直接使用fatalError函数抛出错误。
注:使用了fatalError函数,就不需要再写return

    func divide(_ v1: Int, _ v2: Int) -> Int {
        if v2 != 0 {
            return v1 / v2
        }
        fatalError("除数不能为0")
    }

6、defer

defer语句:用来定义以任何方式(抛错误、return等)离开代码块前必须要执行的代码,也就是说defer语句将延迟至当前作用域结束之前执行

    func open(_ filename: String) -> Int {
        print("open")
        return 0
    }
    
    func close(_ file: Int) {
        print("close")
    }
    
    func processFile(_ filename: String) throws {
        let file = open(filename)
        defer {
            close(file)
        }
        
        // 程序执行到这里会停止,停止之前会调用 defer 中的 close方法
        print(try divide(20, 0))
        
        // close将会在这里调用
        
    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容