[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开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

Java Optional避免空指针异常的实现

《JavaOptional避免空指针异常的实现》空指针异常一直是困扰开发者的常见问题之一,本文主要介绍了JavaOptional避免空指针异常的实现,帮助开发者编写更健壮、可读性更高的代码,减少因... 目录一、Optional 概述二、Optional 的创建三、Optional 的常用方法四、Optio

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

Java异常架构Exception(异常)详解

《Java异常架构Exception(异常)详解》:本文主要介绍Java异常架构Exception(异常),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. Exception 类的概述Exception的分类2. 受检异常(Checked Exception)

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark