美文网首页
Swift 异常处理

Swift 异常处理

作者: 張無忌 | 来源:发表于2017-09-28 11:20 被阅读59次

异常的由来

在写代码的过程中,我们不能保证自己的每一行代码,都能够正确地执行。不能保证每一个函数,都会返回我们所期望的值。所以很多编程语言,都引入了异常处理机制,来让我们得知执行失败的原因,从而可以做出应对。

举例:在读取某个磁盘中的文件时,可能遇到打开磁盘失败文件不存在等错误。

使用可选来处理简单的异常

在 Swift 中有可选的机制,可以解决函数返回不成功的问题,我们经常写出如下代码:

/// 计算
func caculator() -> Double? {
    // XXX
}

然后调用这个函数

if let result = caculator() {
    print(result)
} else {
    print("计算错误")
}

通过可选机制,可以应对一些简单的错误处理。当返回了正确的值,我们可以进行下一步操作,当返回nil,则表示计算过程中发生了错误。但是当出现问题的原因比较多的时候,nil的表现力就显得很弱。所以,接下来介绍异常处理

认识异常处理

假设有这样一个场景:汽车启动,当使用的钥匙正确,才能开启汽车。当燃油大于5升才可以成功启动,否则启动不成功。

我们首先定义一个枚举,来描述汽车启动失败可能的每种情况。针对燃油不足的情况,我们还设置了关联值来提醒用户还差多少油才能启动。

// 描述汽车出问题的各种情况
enum CarError: Error {
    case keyError    // 钥匙不对
    case outOfFuel(fuelNeed: Double)    // 燃油不足
}

接着定义汽车模型。

struct Car {
    // 当前燃油
    var fuelInLitre: Double
    // 汽车的钥匙
    var keyName: String

    // 启动汽车
    func start() throws -> String {
        guard keyName == "trueKey" else {
            throw CarError.keyError
        }
        guard fuelInLitre > 5 else {
            throw CarError.outOfFuel
        }
        return "启动成功"
    }
}

假设正确的钥匙名称为trueKey。这里使用了throws关键字,来表示start方法在执行过程中,可能会抛出异常。throws需要写在->前面。

接着,尝试调用以上的代码。

let car = Car(fuelInLitre: 6, keyName: "trueKey")
do {
    let message = try car.start()
    print(message)
} catch CarError.keyError {
    print("钥匙不正确")
} catch CarError.outOfFuel(let fuelNeed) {
    print("燃油不足,还需要:\(fuelNeed)")
} catch {
    print("发生了其他错误")
}

我们先是定义了一个Car的实例,接着尝试调用start方法,因为这个方法可能会抛出异常,所以必须包含在do的代码块里面,在调用方法前面加上try关键字。调用完毕后,我们就当这个方法能调用成功,继续写成功之后的代码,输出启动信息。

接着使用catch关键字,来捕获可能抛出的异常,并对异常进行处理,我们可能会打印错误日志,或者提示一些有用的信息。

事实上我们只定义了两种可能发生的异常,但是编译时Xcode 9会报错,必须在最后面再加一个catch来表示发了生其他的错误,有点类似于switch语句最后那个default

其他补充

除了try关键字,还有try?try!关键字。try?和可选机制很类似,当方法抛出异常,就会返回一个nil
还是上面汽车启动的例子,我们可以这样写:

let car = Car(fuelInLitre: 3, keyName: "trueKey")
if let message = try? car.start() {
    print(message)
} else {
    print("启动错误,具体原因不知")
}

就不去判断那么多的异常情况,如果返回nil,就代表发生了异常,具体原因不关心。

try!关键字和强制解包很类似,当你认为某个方法一定能执行成功不会抛出异常时,就用它。但是万一抛出了异常,那么程序就崩溃。

let car = Car(fuelInLitre: 6, keyName: "trueKey")
// 强制执行,如果失败,程序直接崩溃
let message = try! car.start()
print(message)

在介绍defer关键字之前,假设:当我们尝试开启一辆汽车,无论启动成功,或是启动失败,都会在最后关闭车门。首先为Car模型新增一个方法closeDoor()

func closeDoor() {
    print("关好车门")
}

然后使用defer关键字,调用。

// 打开了汽车的车门
let car = Car(fuelInLitre: 6, keyName: "trueKey")
// 延时执行,无论 start 方法执行成功或者失败,我们都调用方法来关闭车门
defer {
    car.closeDoor()
}
do {
    let message = try car.start()
    print(message)
} catch CarError.keyError {
    print("钥匙不正确")
} catch CarError.outOfFuel(let fuelNeed) {
    print("燃油不足,还需要:\(fuelNeed)")
} catch {
    print("发生了其他错误")
}

defer关键字,当你的代码无论是正常的执行了,或者是抛出了异常,都会去调用defer代码块里面的语句,多用于做一些清理的工作。

上面的例子比较牵强,另外举一个十分常见的场景:我们尝试打开磁盘,去读取某个文件时,无论读取成功还是失败,都会在最后关闭磁盘。

相关文章

  • swift异常处理

    swift像其他编程语言一样可以抛出异常并处理异常,本文就详细说一下在swift中抛出并处理异常,swift中的一...

  • Swift-异常处理四种方式

    跟其它语言一样,Swift的异常处理是在程序抛出异常后的处理逻辑。 Swift提供了一流的异常抛出、捕获和处理的能...

  • SQLite.swift的使用

    知识储备:swift中异常处理 SQLite.swift这个库中有很多的异常处理,详细了解请点击下面的地址: Sw...

  • Swift - 异常处理

    说明 跟其它语言一样,Swift的异常处理是在程序抛出异常后的处理逻辑。 Swift提供了一流的异常抛出、捕获和处...

  • Swift备忘

    Swift初体验 Swift Tips Swift三种不同的【异常处理方式】 Swift 3.0 private变...

  • Swift 处理异常

    处理方式 定义异常类型 在 Swift 中,错误用符合Error协议的类型的值来表示。这个空协议表明该类型可以用于...

  • swift——异常处理

    FileManager.swift ViewController.swift

  • swift 异常处理

    序言 对异常的正确处理能够明确反映在代码执行中出现的问题,使得在接下来的debug快速定位问题所在的地方,提高de...

  • Swift 异常处理

    异常的由来 在写代码的过程中,我们不能保证自己的每一行代码,都能够正确地执行。不能保证每一个函数,都会返回我们所期...

  • Swift - 异常处理

    Swift提供了一流的异常抛出、捕获和处理 能力,跟JAVA语言类似。Swift的异常并不是真正的程序崩溃, 而是...

网友评论

      本文标题:Swift 异常处理

      本文链接:https://www.haomeiwen.com/subject/lngxextx.html