Swift Protocols(协议)、Extensions(扩展)、Error Handling(错误处理)、Generics(泛型)

最近在学习 Swift,总结相关知识


1. Protocols(协议)

1.1 协议的定义和实现

  • 协议(protocol 是一种定义方法和属性的蓝图,任何类、结构体或枚举都可以遵循协议。
  • 遵循协议后,需要实现协议中定义的所有内容。
示例
protocol ExampleProtocol {var simpleDescription: String { get }mutating func adjust()
}
  • simpleDescription 定义了一个只读属性。
  • mutating 标记方法可以修改遵循协议的值类型(如结构体、枚举)。
实现协议
  • 类(class 遵循协议:

    class SimpleClass: ExampleProtocol {var simpleDescription: String = "A very simple class."var anotherProperty: Int = 69105func adjust() {simpleDescription += " Now 100% adjusted."}
    }
    
    • 方法 adjust 可以直接修改属性,无需标记为 mutating
  • 结构体(struct 遵循协议:

    struct SimpleStructure: ExampleProtocol {var simpleDescription: String = "A simple structure"mutating func adjust() {simpleDescription += " (adjusted)"}
    }
    
    • mutating 必须添加,因为结构体是值类型,默认情况下,方法不能修改实例。

1.2 扩展协议要求

向协议 ExampleProtocol 添加新的要求:

protocol ExampleProtocol {var simpleDescription: String { get }mutating func adjust()func detailedDescription() -> String
}class SimpleClass: ExampleProtocol {var simpleDescription: String = "A very simple class."func adjust() {simpleDescription += " Now 100% adjusted."}func detailedDescription() -> String {return "This is \(simpleDescription)"}
}struct SimpleStructure: ExampleProtocol {var simpleDescription: String = "A simple structure"mutating func adjust() {simpleDescription += " (adjusted)"}func detailedDescription() -> String {return "This is \(simpleDescription)"}
}

2. Extensions(扩展)

2.1 扩展定义

扩展可以用来为现有的类、结构体、枚举或协议添加功能,例如添加方法、计算属性或协议一致性。

示例:扩展 Int
extension Int: ExampleProtocol {var simpleDescription: String {return "The number \(self)"}mutating func adjust() {self += 42}
}
print(7.simpleDescription) // 输出:The number 7
实验:扩展 Double 添加 absoluteValue
extension Double {var absoluteValue: Double {return self >= 0 ? self : -self}
}
print((-3.14).absoluteValue) // 输出:3.14

3. Error Handling(错误处理)

3.1 错误类型

  • Swift 的错误类型必须遵循 Error 协议,通常用 enum 定义。
enum PrinterError: Error {case outOfPapercase noTonercase onFire
}

3.2 抛出和捕获错误

  • 使用 throw 抛出错误,使用 throws 标记函数可能抛出错误。
  • 使用 do-catch 捕获错误。
示例
func send(job: Int, toPrinter printerName: String) throws -> String {if printerName == "Never Has Toner" {throw PrinterError.noToner}return "Job sent"
}do {let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")print(printerResponse)
} catch PrinterError.noToner {print("No toner available.")
} catch {print(error)
}

3.3 使用 try?defer

  • try? 抛出错误时返回 nil
  • defer 无论函数是否抛出错误,都执行清理代码。
示例
let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler")
let printerFailure = try? send(job: 1885, toPrinter: "Never Has Toner")func fridgeContains(_ food: String) -> Bool {defer { print("Fridge closed.") } // 确保清理return ["milk", "eggs"].contains(food)
}

4. Generics(泛型)

4.1 泛型函数

  • 泛型允许编写通用代码,支持多种类型。
func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {var result: [Item] = []for _ in 0..<numberOfTimes {result.append(item)}return result
}
makeArray(repeating: "knock", numberOfTimes: 4)

4.2 泛型类型

  • 例如,重新实现 Swift 标准库的 Optional 类型:
enum OptionalValue<Wrapped> {case nonecase some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)

4.3 泛型约束

  • 使用 where 指定类型约束。
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Boolwhere T.Element: Equatable, T.Element == U.Element {for lhsItem in lhs {for rhsItem in rhs {if lhsItem == rhsItem {return true}}}return false
}
anyCommonElements([1, 2, 3], [3])
实验:返回公共元素数组
func commonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Element]where T.Element: Equatable, T.Element == U.Element {var result: [T.Element] = []for lhsItem in lhs {if rhs.contains(lhsItem) {result.append(lhsItem)}}return result
}
print(commonElements([1, 2, 3], [3, 4, 5])) // 输出:[3]

总结

Swift 提供了许多现代化特性:

  1. Protocols 和 Extensions: 提供灵活的功能扩展和一致性约束。
  2. Error Handling: 提供 throwdo-catchtry? 等灵活的错误处理机制。
  3. Generics: 支持编写通用、高效、类型安全的代码。
  4. 类型安全性: Swift 的类型系统可以有效防止运行时错误,提升代码可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/65189.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uni-app开发-习惯养成小程序/app介绍

目录 一:功能概述 二:功能部分代码和截图 一:功能概述 1 习惯目标生成 创建习惯:用户可以添加新的习惯目标,每个习惯可以包含名称、描述、图标、目标天数。 关联习惯完成:用户通过设定达成目标以后,生成习惯养成记录。 2 习惯打卡 简单快捷的打卡:提供一个直观的界面…

【HTML】Day02

【HTML】Day02 1. 列表标签1.1 无序列表1.2 有序列表1.3 定义列表 2. 表格标签2.1 合并单元格 3. 表单标签3.1 input标签基本使用3.2 上传多个文件 4. 下拉菜单、文本域5. label标签6. 按钮button7. div与span、字符实体字符实体 1. 列表标签 作用&#xff1a;布局内容排列整齐…

基于Spring Boot的车辆违章信息管理系统(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

Git - 记录一次由于少输入了一个命令导致的更改丢失

Git - 记录一次由于少输入了一个参数导致的更改丢失 前言 某晚我激情开发了几个小时&#xff0c;中途没有进行commit存档。准备睡觉时&#xff0c;我想创建一个新的分支并将今晚所有更改提交到新分支上&#xff08;似乎应该开发时候就创建&#xff1f;&#xff09;。 然后因…

探索Rust在Web开发中的实际应用

近年来&#xff0c;Rust语言因其高性能、内存安全性和强大的工具链支持而迅速崛起。在Web开发领域&#xff0c;Rust提供了一套高效、现代化的框架和工具&#xff0c;使得开发者能够构建快速、安全的Web应用程序。在本文中&#xff0c;我们将深入探讨如何使用Rust进行Web开发&am…

Apache Celeborn 在B站的生产实践

背景介绍 Shuffle 演进 随着B站业务的飞速发展,数据规模呈指数级增长,计算集群也逐步从单机房扩展到多机房部署模式。多个业务线依托大数据平台驱动核心业务,大数据系统的高效性与稳定性成为公司业务发展的重要基石。如图1,目前在大数据基础架构下,我们主要采用 Spark、Fl…

第29天:Web开发-PHP应用弱类型脆弱Hash加密Bool类型Array数组函数转换比较

#知识点 1、安全开发-原生PHP-弱类型脆弱 2、安全开发-原生PHP-函数&数据类型 3、安全开发-原生PHP-代码审计案例 一、PHP弱类型对比 1、 和 两个等号是弱比较&#xff0c;使用进行对比的时候&#xff0c;php解析器就会做隐式类型转换&#xff0c;如果两个值的类型不相等就…

Kafaka安装与启动教程

1.下载 先去官网Apache Kafka可以查看到每个版本的发布时间。选择你要安装的版本。 然后进入linux建立要存放的文件夹&#xff0c;用wget命令下载 2.安装 先解压缩&#xff1a; tar -xvzf kafka_2.12-3.5.1.tgz -C ../ 3.配置文件 修改server.properties&#xff1a; cd .…

回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测

回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测 目录 回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 一、极限学习机&#xff08;ELM&#xff09; 极限学习机是一种单层前馈神经网络&#xff0c;具有训练速…

1、pycharm、python下载与安装

1、去官网下载pycharm 官网&#xff1a;https://www.jetbrains.com/pycharm/download/?sectionwindows 2、在等待期间&#xff0c;去下载python 进入官网地址&#xff1a;https://www.python.org/downloads/windows/ 3、安装pycharm 桌面会出现快捷方式 4、安装python…

GESP2023年12月认证C++五级( 第三部分编程题(1)小杨的幸运数)

参考程序&#xff1a; #include <iostream> #include <cmath> using namespace std;int nextPerfectSquare(int a) {int sqrt_a (int)sqrt(a);if (sqrt_a * sqrt_a < a) {sqrt_a; // 如果 sqrt(a) 的平方小于 a&#xff0c;那么就需要加 1&#xff0c;找到下…

25年1月更新。Windows 上搭建 Python 开发环境:Python + PyCharm 安装全攻略(文中有安装包不用官网下载)

引言 随着 Python 在数据科学、Web 开发、自动化脚本等多个领域的广泛应用&#xff0c;越来越多的开发者选择它作为首选编程语言。而 PyCharm 作为一个功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;为 Python 开发者提供了极大的便利。本文将详细介绍如何在 …

IDEA配置maven和git并如何使用maven打包和git推送到gitlab

首先找到设置 在里面输入maven然后找到点击 然后点击右边两个选项 路径选择下载的maven目录下的settings文件和新建的repository文件夹 点击apply应用 然后在搜索框里搜git点击进去 此路径为git的exe执行文件所在目录&#xff0c;选好之后点击test测试下方出现git版本号表…

【Rust 知识点杂记】

1、self和Self 在Rust中&#xff0c;self 和 Self 有不同的含义和用法&#xff0c;它们通常出现在结构体、枚举或实现&#xff08;impl&#xff09;块的上下文中。 self: self 是一个关键字&#xff0c;它代表方法调用时实例本身的引用。当在一个方法定义中使用 self 作为第一…

【Vue学习】Vue 组件实例的生命周期(四个阶段,八个钩子)

一、为什么要理解生命周期&#xff1f; 理解生命周期就像是知道了一部电影的剧情走向&#xff0c;能让你在适当的时机做出反应。Vue 生命周期的钩子让你可以在不同的阶段插入你的逻辑&#xff0c;像是提前准备、后期清理或者在数据更新时做点事情。这种“精确控制”的能力会让你…

【Vue】<script setup>和 <script>区别是什么?在使用时的写法区别?

<script setup> 是 Vue 3 引入的一种新的脚本语法&#xff0c;它提供了一种更简洁和声明式的方式来编写组件逻辑。它是为了解决传统 <script> 标签在 Vue 单文件组件&#xff08;SFC&#xff09;中的一些局限性而设计的。 <script setup> 与 <script>…

Kotlin 数据类与密封类

Kotlin 数据类与密封类 引言 在 Kotlin 中&#xff0c;数据类和密封类是两种非常重要的类类型&#xff0c;它们各自具有独特的用途和优势。数据类主要用于存储数据&#xff0c;而密封类则用于表示受限的类层次结构。在本篇文章中&#xff0c;我们将深入探讨 Kotlin 中的数据类…

Linux之信号量

目录 信号量 信号量相关接口 创建信号量 初始化信号量 等待信号量&#xff0c;P操作 发布信号量&#xff0c;V操作 销毁信号量 基于信号量的环形队列下的生产者和消费者模型 环形队列 代码实现 上期我们学习了线程同步的概念&#xff0c;掌握了基于阻塞队列的生产…

【电子通识】PWM驱动让有刷直流电机恒流工作

电机的典型驱动方法包括电压驱动、电流驱动以及PWM驱动。本文将介绍采用PWM驱动方式的恒流工作。 首先介绍的是什么是PWM驱动的电机恒流工作&#xff0c;其次是PWM驱动电机恒流工作时电路的工作原理。 PWM驱动 当以恒定的电流驱动电机时&#xff0c;电机会怎样工作呢&#xff1…

非docker方式部署openwebui过程记录

之前一直用docker方式部署openwebui&#xff0c;结果这东西三天两头升级&#xff0c;我这一升级拉取docker镜像硬盘空间嗖嗖的占用&#xff0c;受不了&#xff0c;今天改成了直接部署&#xff0c;以下是部署过程记录。 一、停止及删除没用的docker镜像占用的硬盘空间 docker s…