[Swift 开发] 异常俘获 Do_Try_Catch

2024-05-06 18:48

本文主要是介绍[Swift 开发] 异常俘获 Do_Try_Catch,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

定义抛出Throw类型

表示和抛出错误 在 Swift 中,错误由符合 Error 协议的类型值表示。这个空协议表明一个类型可用于错误处理。

Swift 枚举特别适合对一组相关的错误条件进行建模,关联的值允许传达有关要传达的错误性质的附加信息。

例如,您可以通过以下方式表示在游戏中操作自动售货机的错误条件:

    enum VendingMachineError: Error {case invalidSelectioncase insufficientFunds(coinsNeeded: Int)case outOfStock}

抛出错误让您表明发生了意外情况,正常的执行流程无法继续。使用 throw 语句抛出错误。例如,下面的代码会抛出一个错误,表明自动售货机还需要 5 个额外的硬币:

throw VendingMachineError.insufficientFunds(coinsNeeded: 5)

函数中Throw的运用

要指示函数、方法或初始化程序可以抛出错误,请在函数声明中的参数后面编写 throws 关键字。

标有 throws 的函数称为 throwing 函数。

如果函数指定了返回类型,则在返回箭头 (->) 之前编写 throws 关键字。

    func canThrowErrors() throws -> Stringfunc cannotThrowErrors() -> String

在下面的示例中,VendingMachine 类有一个 vend(itemNamed:) 方法,如果请求的项目不可用、缺货或成本超过当前存入的金额,则该方法会抛出适当的 VendingMachineError

    struct Item {var price: Intvar count: Int}class VendingMachine {var inventory = ["Candy Bar": Item(price: 12, count: 7),"Chips": Item(price: 10, count: 4),"Pretzels": Item(price: 7, count: 11)]var coinsDeposited = 0func vend(itemNamed name: String) throws {guard let item = inventory[name] else {throw VendingMachineError.invalidSelection}guard item.count > 0 else {throw VendingMachineError.outOfStock}guard item.price <= coinsDeposited else {throw VendingMachineError.insufficientFunds(coinsNeeded: item.price - coinsDeposited)}coinsDeposited -= item.pricevar newItem = itemnewItem.count -= 1inventory[name] = newItemprint("Dispensing \(name)")}}

vend(itemNamed:) 方法的实现使用保护语句提前退出该方法并在不满足购买零食的任何要求时抛出适当的错误。因为 throw 语句会立即转移程序控制,所以只有满足所有这些要求才会出售项目。

因为 vend(itemNamed:) 方法会传播它抛出的任何错误,所以任何调用此方法的代码都必须处理这些错误——使用 do-catch 语句、try? 或 try!——或者继续传递它们。

例如,下例中的 buyFavoriteSnack(person:vendingMachine:) 也是一个抛出函数,并且 vend(itemNamed:) 方法抛出的任何错误都会传递到 buyFavoriteSnack(person:vendingMachine:)

    let favoriteSnacks = ["Alice": "Chips","Bob": "Licorice","Eve": "Pretzels",]func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {let snackName = favoriteSnacks[person] ?? "Candy Bar"try vendingMachine.vend(itemNamed: snackName)}

在这个例子中,buyFavoriteSnack(person: vendingMachine:) 函数查找给定人最喜欢的零食,并尝试通过调用 vend(itemNamed:) 方法为他们购买。由于 vend(itemNamed:) 方法可能会抛出错误,因此在调用它时会在其前面加上 try 关键字。 抛出初始化器可以以与抛出函数相同的方式传递错误。

例如,下面清单中的 PurchasedSnack 结构的初始化程序调用一个抛出函数作为初始化过程的一部分,它通过将它们传递给它的调用者来处理它遇到的任何错误。

    struct PurchasedSnack {let name: Stringinit(name: String, vendingMachine: VendingMachine) throws {try vendingMachine.vend(itemNamed: name)self.name = name}}

使用 Do_Try_Catch 处理错误

您可以使用 do-catch 语句通过运行代码块来处理错误。如果 do 子句中的代码抛出错误,则它会与 catch 子句进行匹配,以确定它们中的哪一个可以处理错误。

以下是 do-catch 语句的一般形式:

    do {try expressionstatements} catch pattern 1 {statements} catch pattern 2 where condition {statements} catch pattern 3, pattern 4 where condition {statements} catch {statements}

在 catch 之后编写一个模式来指示该子句可以处理哪些错误。如果 catch 子句没有模式,则该子句匹配任何错误并将错误绑定到名为 error 的本地常量。

例如,以下代码与 VendingMachineError 枚举的所有三种情况相匹配。

    var vendingMachine = VendingMachine()vendingMachine.coinsDeposited = 8do {try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)print("Success! Yum.")} catch VendingMachineError.invalidSelection {print("Invalid Selection.")} catch VendingMachineError.outOfStock {print("Out of Stock.")} catch VendingMachineError.insufficientFunds(let coinsNeeded) {print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")} catch {print("Unexpected error: \(error).")}// Prints "Insufficient funds. Please insert an additional 2 coins."

在上面的示例中,在 try 表达式中调用了 buyFavoriteSnack(person:vendingMachine:) 函数,因为它会抛出错误。如果抛出错误,则执行立即转移到 catch 子句,它决定是否允许继续传递。如果没有匹配的模式,错误会被最后的 catch 子句捕获并绑定到一个局部错误常量。如果没有抛出错误,则执行 do 语句中的其余语句。

捕获几个相关错误的另一种方法是在 catch 之后列出它们,用逗号分隔。例如

    func eat(item: String) throws {do {try vendingMachine.vend(itemNamed: item)} catch VendingMachineError.invalidSelection, VendingMachineError.insufficientFunds, VendingMachineError.outOfStock {print("Invalid selection, out of stock, or not enough money.")}}

eat(item:) 函数列出要捕获的自动售货机错误,其错误文本对应于该列表中的项目。如果抛出列出的三个错误中的任何一个,这个 catch 子句通过打印一条消息来处理它们。 其它的异常会继续上传递Throw

将Throw转换为Optional类型

你用try?通过将错误转换为可选值来处理错误。如果在评估 try 时抛出错误?表达式,表达式的值为 nil。例如,在以下代码中,x 和 y 具有相同的值和行为:

    func someThrowingFunction() throws -> Int {// ...}let x = try? someThrowingFunction()let y: Int?do {y = try someThrowingFunction()} catch {y = nil}

如果 someThrowingFunction() 抛出错误,则 x 和 y 的值为零。否则,x 和 y 的值就是函数返回的值。请注意, x 和 y 是 someThrowingFunction() 返回的任何类型的可选项。这里函数返回一个整数,所以 x 和 y 是可选的整数。

使用try?当您想以相同的方式处理所有错误时,让您可以编写简洁的错误处理代码。例如,以下代码使用多种方法来获取数据,如果所有方法都失败,则返回 nil。

    func fetchData() -> Data? {if let data = try? fetchDataFromDisk() { return data }if let data = try? fetchDataFromServer() { return data }return nil}

这篇关于[Swift 开发] 异常俘获 Do_Try_Catch的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/965078

相关文章

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

解决java.lang.NullPointerException问题(空指针异常)

《解决java.lang.NullPointerException问题(空指针异常)》本文详细介绍了Java中的NullPointerException异常及其常见原因,包括对象引用为null、数组元... 目录Java.lang.NullPointerException(空指针异常)NullPointer

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

使用Go语言开发一个命令行文件管理工具

《使用Go语言开发一个命令行文件管理工具》这篇文章主要为大家详细介绍了如何使用Go语言开发一款命令行文件管理工具,支持批量重命名,删除,创建,移动文件,需要的小伙伴可以了解下... 目录一、工具功能一览二、核心代码解析1. 主程序结构2. 批量重命名3. 批量删除4. 创建文件/目录5. 批量移动三、如何安

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

基于Python开发PPTX压缩工具

《基于Python开发PPTX压缩工具》在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,不便于传输和存储,所以本文将使用Python开发一个PPTX压缩工具,需要的可以了解下... 目录引言全部代码环境准备代码结构代码实现运行结果引言在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,

Spring Boot统一异常拦截实践指南(最新推荐)

《SpringBoot统一异常拦截实践指南(最新推荐)》本文介绍了SpringBoot中统一异常处理的重要性及实现方案,包括使用`@ControllerAdvice`和`@ExceptionHand... 目录Spring Boot统一异常拦截实践指南一、为什么需要统一异常处理二、核心实现方案1. 基础组件

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做