Swift 错误处理

在本教程中,我们将通过示例学习如何处理 Swift 错误。

错误(异常)是程序执行期间发生的意外事件。例如,

  1. var numerator = 10
  2. var denominator = 0
  3. // try to divide a number by 0
  4. var result = numerator / denominator // error code

这里,我们试图除数。因此,这类错误会导致程序异常终止。


Swift 错误处理步骤

  1. 创建表示错误类型的枚举。

  2. 使用 throws 关键字创建抛出函数。

  3. 使用 try 关键字调用函数。

  4. do{…} 块中用 try 包裹代码,并添加 catch{…} 块来处理所有错误。


1. 创建错误枚举

在 Swift 中,我们需要创建一个枚举来表示在编写程序时可能遇到的错误类型。

我们创建的枚举必须符合 Error 协议,以便我们可以在函数内抛出错误值。

让我们看一个例子,

  1. enum DivisionError: Error {
  2. case dividedByZero
  3. }

在这里,我们创建了一个名为 DivisionError 的枚举,其值为 dividedByZero

由于 DivisionError 符合 Error 协议,我们现在可以抛出枚举的错误值。


2. 创建抛出函数

为了抛出错误,我们需要使用 throws 关键字创建抛出函数。

然后,我们在函数中使用 throw 语句来抛出由枚举表示的特定错误。例如,

  1. // create throwing function using throws keyword
  2. func division(numerator: Int, denominator: Int) throws {
  3. // throw error if divide by 0
  4. if denominator == 0 {
  5. throw DivisionError.dividedByZero
  6. }
  7. ...
  8. }

在这里,我们使用 throw 关键字创建了一个名为 division() 的抛出函数。如果 denominator == 0,函数抛出 DivisionError 枚举的 dividedByZero 值。

现在,根据函数调用期间传递的值,如果满足错误条件,函数将抛出错误。

注意throw 关键字与 return 关键字具有相同的效果。return 从函数返回一些值,而 throw 从函数返回错误值。


3. 使用 try 关键字进行函数调用

在 Swift 中,我们在调用抛出函数时使用 try 关键字。它表示函数可能引发错误。例如,

  1. // call throwing function using try keyword
  2. try division(numerator: 10, denominator: 0)

然而,错误处理过程仍不完整。如果我们现在运行该程序,我们将得到一条错误消息:An error was thrown and was not caught

因此,为了捕获抛出的错误,我们使用 do-catch 语句。


4. 使用 do-catch 语句处理错误

在 Swift 中,我们将 try 代码包在 do 块中,并添加 catch 块来处理所有错误。例如,

  1. do {
  2. try division(numerator: 10, denominator: 0)
  3. ...
  4. }
  5. catch DivisionError.dividedByZero {
  6. // statement
  7. }

这里,我们从 do 块中调用了抛出函数 division(),并附加了 catch 块以在函数抛出错误时捕获错误。

上述 catch 块基于 DivisionError 的枚举值执行。

这是处理程序中可能出现的错误的最后一步。


实例:错误处理

  1. // create an enum with error values
  2. enum DivisionError: Error {
  3. case dividedByZero
  4. }
  5. // create a throwing function using throws keyword
  6. func division(numerator: Int, denominator: Int) throws {
  7. // throw error if divide by 0
  8. if denominator == 0 {
  9. throw DivisionError.dividedByZero
  10. }
  11. else {
  12. let result = numerator / denominator
  13. print(result)
  14. }
  15. }
  16. // call throwing function from do block
  17. do {
  18. try division(numerator: 10, denominator: 0)
  19. print("Valid Division")
  20. }
  21. // catch error if function throws an error
  22. catch DivisionError.dividedByZero {
  23. print("Error: Denominator cannot be 0")
  24. }

结果如下:

  1. Error: Denominator cannot be 0

在上面的例子中,

  • DivisionError 是一个枚举

  • division() 是一个抛出函数

  • do-catch 语句处理错误

我们曾尝试将值传递给抛出函数

  1. try division(numerator: 10, denominator: 0)

如果错误条件为

  • 满足条件 - 抛出函数抛出错误,该错误被 catch 块捕获。

  • 不满足条件- 抛出函数中的 else 语句和 do 块中的 print 语句被执行。


禁用错误处理

在 Swift 中,有时我们可以确信抛出函数在运行时不会抛出错误。

那样的话,我们可以写试试!在函数调用期间禁用错误处理。例如,

  1. enum DivisionError: Error {
  2. case dividedByZero
  3. }
  4. func division(numerator: Int, denominator: Int) throws {
  5. if denominator == 0 {
  6. throw DivisionError.dividedByZero
  7. }
  8. else {
  9. let result = numerator / denominator
  10. print("Result:", result)
  11. }
  12. }
  13. // disable error handling
  14. try! division(numerator: 10, denominator: 5)

结果如下:

  1. Result: 2

在上面的例子中,我们使用了 try! 在函数调用期间禁用错误处理。

  1. try! division(numerator: 10, denominator: 5)

在这里,由于我们给 denominator 赋值 5,我们知道程序不会抛出错误。因此,我们禁用了错误处理。

还请注意,当我们使用 try! 时!,我们不需要使用 do-catch 语句。

注意:如果我们使用 try! 还有错误,那么我们的应用程序会崩溃。

Swift 错误的原因

出现错误的原因有很多。其中一些是:

  • 用户输入无效
  • 设备故障
  • 网络连接中断
  • 物理限制(磁盘内存不足)
  • 代码错误
  • 打开不可用的文件

由于错误会异常终止程序的执行,因此处理此类错误非常重要。