Swift 开发教程系列 - 第12章:协议与协议扩展
协议(Protocol)是 Swift 的一种重要特性,它定义了实现特定功能的方法、属性或其他要求。通过协议,可以将行为定义从具体实现中分离,使代码更具可读性和扩展性。Swift 的协议支持协议扩展,这一特性允许我们为协议定义默认实现,使得协议不仅仅是一个要求的集合,还可以具备部分功能。
12.1 什么是协议
协议定义了一组用于实现特定功能的方法或属性。任何符合该协议的类型都必须实现这些方法和属性,确保符合协议的类型拥有相似的功能和行为。
协议示例
protocol Drivable {var speed: Double { get set }func drive()
}class Car: Drivable {var speed: Double = 0.0func drive() {print("Driving at \(speed) km/h")}
}let myCar = Car()
myCar.speed = 80.0
myCar.drive() // 输出:"Driving at 80.0 km/h"
在上例中,Drivable 协议要求任何符合该协议的类型都必须实现 speed 属性和 drive() 方法。Car 类遵循 Drivable 协议,并提供了具体的实现。
12.2 协议中的属性和方法
协议不仅可以定义方法,还可以定义属性和下标(subscript)。协议中的属性可以是只读的,也可以是可读写的。
- 只读属性:使用 { get } 声明只读属性,符合该协议的类型必须实现此属性。
- 可读写属性:使用 { get set } 声明可读写属性,符合该协议的类型必须支持读取和写入。
示例代码
protocol Identifiable {var id: String { get }
}struct User: Identifiable {var id: String
}let user = User(id: "12345")
print("User ID: \(user.id)") // 输出:"User ID: 12345"
在上例中,Identifiable 协议定义了一个只读属性 id,符合协议的类型 User 实现了此属性。
12.3 协议的继承
Swift 的协议支持继承,可以从一个协议继承多个协议,并添加自己的要求。
示例代码
protocol Vehicle {var maxSpeed: Double { get }
}protocol Drivable: Vehicle {func drive()
}class Bicycle: Drivable {var maxSpeed: Double = 25.0func drive() {print("Cycling at a safe speed.")}
}let bike = Bicycle()
bike.drive() // 输出:"Cycling at a safe speed."
在上例中,Drivable 协议继承自 Vehicle 协议,这意味着任何符合 Drivable 的类型必须同时满足 Vehicle 的要求。
12.4 协议组合
Swift 支持将多个协议组合在一起,定义一个新类型,该类型必须同时符合多个协议的要求。
示例代码
protocol Named {var name: String { get }
}protocol Aged {var age: Int { get }
}struct Person: Named, Aged {var name: Stringvar age: Int
}func printInfo(of person: Named & Aged) {print("\(person.name) is \(person.age) years old")
}let alice = Person(name: "Alice", age: 30)
printInfo(of: alice) // 输出:"Alice is 30 years old"
在上例中,函数 printInfo 的参数类型 Named & Aged 表示参数必须同时符合 Named 和 Aged 协议。
12.5 协议扩展
协议扩展允许你为协议提供默认实现,使得符合该协议的类型可以直接使用这些实现,而无需自行实现。这样可以避免代码重复,并使协议的行为更为一致。
示例代码
protocol Greetable {var name: String { get }func greet()
}extension Greetable {func greet() {print("Hello, \(name)!")}
}struct Friend: Greetable {var name: String
}let friend = Friend(name: "John")
friend.greet() // 输出:"Hello, John!"
在上例中,Greetable 协议的扩展提供了 greet() 方法的默认实现,因此符合协议的 Friend 结构体可以直接调用 greet() 方法,而无需自己实现。
12.6 协议的应用场景
- 接口设计:通过协议定义模块的公共接口,使代码更具模块化和可读性。
- 依赖注入:使用协议替代具体类型,可以实现更灵活的依赖注入。
- 委托模式:在委托模式中,协议用于定义委托对象的方法和属性,使不同类型的对象可以通过协议进行交互。
- 类型约束:在泛型编程中,使用协议作为类型约束,确保泛型类型符合特定要求。
委托模式示例
protocol DataSource {func fetchData() -> [String]
}class TableView {var dataSource: DataSource?func reloadData() {if let data = dataSource?.fetchData() {print("Data: \(data)")}}
}class DataProvider: DataSource {func fetchData() -> [String] {return ["Item 1", "Item 2", "Item 3"]}
}let tableView = TableView()
tableView.dataSource = DataProvider()
tableView.reloadData() // 输出:"Data: ["Item 1", "Item 2", "Item 3"]"
在上例中,DataSource 协议定义了 fetchData() 方法,使 TableView 类不需要知道具体的数据来源,而是通过协议获取数据。
12.7 协议的优点
- 灵活性:协议可以帮助实现松耦合的设计,使代码更具模块化和灵活性。
- 可扩展性:协议扩展使得协议不只是一个要求的集合,还可以包含默认实现,方便扩展协议的功能。
- 代码复用:通过协议和协议扩展,可以避免重复代码,提高代码的复用性。
- 类型安全:Swift 的类型检查确保协议实现的安全性,避免了运行时错误。
通过本章的学习,你将会发现协议在 Swift 开发中扮演着至关重要的角色,使代码更加灵活、可扩展,并且容易维护。下一章将探讨 Swift 的错误处理机制(Error Handling),帮助你编写更加健壮和稳定的代码。
相关文章:
Swift 开发教程系列 - 第12章:协议与协议扩展
协议(Protocol)是 Swift 的一种重要特性,它定义了实现特定功能的方法、属性或其他要求。通过协议,可以将行为定义从具体实现中分离,使代码更具可读性和扩展性。Swift 的协议支持协议扩展,这一特性允许我们为…...

麒麟V10,arm64,离线安装docker和docker-compose
文章目录 一、下载1.1 docker1.2 docker-compose1.3 docker.service 二、安装三、验证安装成功3.1 docker3.2 docker-compose 需要在离线环境的系统了里面安装docker。目前国产化主推的是麒麟os和鲲鹏的cpu,这块的教程还比较少,记录一下。 # cat /etc/ky…...

NUXT3学习日记二(样式配置、引入组件库、区分在服务端还是在客户端渲染)
上一章已经给大家分享官网下载的nuxt3了,下面正式进入我所要说的内容吧 一、初始化样式 想必大家从我的git下载下来的nuxt3,能看到nuxt.config.ts这个文件了吧。 这里我们有两种css配置方式 1、css:[~/assets/base.scss] 这种方式不能在scss文件中定义…...

FPGA/Verilog,Quartus环境下if-else语句和case语句RT视图对比/学习记录
基本概念 RTL(Register - Transfer - Level)视图:是一种硬件描述语言的抽象层次,用于描述数字电路中寄存器之间的数据传输和操作。在这个层次上,可以看到电路的基本结构,如寄存器、组合逻辑、多路复用器等…...
Javascript高级—闭包问题
闭包问题 循环中赋值为引用的问题 for (var i 1; i < 5; i) {setTimeout(function timer() {console.log(i)}, i * 1000) }解决方法有3种 第一种,使用立即执行函数方式 for (var i 1; i < 5; i) {(fuction(j){setTimeout(function timer() {console.log…...

C#入门 017 字段,属性,索引器,常量
字段,属性,索引器,常量都表示数据 字段 什么是字段 字段(field)是一种表示与对象或类型(类与结构体)关联的变量字段是类型的成员,又称“成员变量,写在类体里面与对象关联的字段亦称“实例字段,表示某个对…...
磐石云语音助手拦截介绍
呼叫中心用户实际应用场景下最高会有超过30%的和语音助手;无声主要是进入了语音信箱;如:“听到滴声后留言”,”漏话提醒““发送请按1,重录请按2”以及拨打过程中客户主动拒接产生的”您拨打的用户正忙“,”关机“”停…...
JSP执行过程及其与Servlet执行效率的比较
JSP(Java Server Pages)和Servlet都是Java Web开发中常用的技术,它们都用于动态生成Web页面。然而,JSP和Servlet在执行过程和效率上存在一些差异。本文将详细探讨JSP的执行过程,并比较JSP与Servlet的执行效率。 一、J…...

open3d
open3d open3d用于 3D 数据处理的现代库。 简介 Open3D 是一个开源库,支持快速开发处理 3D 数据的软件。Open3D 前端公开了一组精心挑选的 C 和 Python 数据结构和算法。后端经过高度优化,并设置为并行化。Open3D 是从零开始开发的,具有一更…...
Vue中优雅的使用Echarts的三种方式
一、原始方法直接使用 1、安装ECharts: npm install echarts --save 2、创建一个Vue公共组件 EChart.vue: <template><div :style"{width: 100%, height: 300px}" ref"chart"></div> </template><scri…...

SpringBoot配置文件/日志
目录 一,SpringBoot配置文件 1,配置文件的格式: 2,properties 3,yml 1,properties与yml的转换 2,读取配置选哪个中的内容 3,单双引号的差异: 4,配置对象: 5,配置集合/配置map 6,yml的优缺点: 二,验证码: 学习目的: 实现样例: 接口定义: 代码总结: 三,日志: 1,概…...
微服务架构面试内容整理-SpringCloud Netflix与Spring Cloud Alibaba比较
Spring Cloud Netflix 和 Spring Cloud Alibaba 都是用于构建微服务架构的解决方案,但它们在设计理念、组件和使用场景上存在一些差异。以下是它们的比较: 1. 服务注册与发现 ● Spring Cloud Netflix:使用 Eureka 作为服务注册和发现的组件。Eureka 是基于 REST 的,适合服…...
JDBC魔法:连接MySQL数据库与数据操作的秘籍
文章目录 一. JDBC介绍二. 数据库驱动1.DriverManager2.Connection3.PreparedStatement4.ResultSet 三. JDBC连接MySQL1. 加载驱动2. 获得连接3. 关闭连接 四. JDBC实现数据新增五. JDBC实现数据删除 一. JDBC介绍 JDBC(Java Database Connectivity)是Ja…...
深入了解Scratch:引导初学者开启编程之旅
引言 在当今数字化时代,编程已不再是成年人的专利,而是一项逐渐向低年龄段普及的技能。Scratch作为一款面向儿童和青少年的图形化编程语言,以其简单易用且充满趣味性的特点,成为了许多初学者学习编程的首选工具。本文将深入探讨S…...
js复制内容到剪切板
复制内容到剪切板 最近预报一个需求需要点击按钮复制当前到行的内容到剪切板, 所以写了这个工具 export function copyText(text: string, prompt: string | null 已成功复制到剪切板!) {if (navigator.clipboard) {return navigator.clipboard.writeText(text).th…...
代码 RNN原理及手写复现
29、PyTorch RNN的原理及其手写复现_哔哩哔哩_bilibili 笔记连接: https://pan.baidu.com/s/1_Sm7ptEiJtTTq3vQWgOTNg?pwd2rei 提取码: 2rei import torch import torch.nn as nn bs,T2,3 # 批大小,输入序列长度 input_size,hidden_size 2,3 # 输入特征大小&a…...
企业官网的在线客服,如何提高效果?
企业官网的在线客服,如何提高效果? 作者:开源呼叫中心系统 FreeIPCC,github地址:https://github.com/lihaiya/freeipcc 提高企业官网在线客服的效果,是提升客户体验、增强客户满意度和忠诚度的关键。一个…...

「实战应用」如何可视化 DHTMLX Scheduler 中的资源工作量?
DHTMLX Scheduler是一个全面的 UI 组件,用于处理面向业务的 Web 应用程序中复杂的调度和任务管理需求。但是,某些场景可能需要自定义解决方案。例如,如果项目的资源(即劳动力)有限,则需要确保以更高的精度分…...

论文阅读《BEVFormer》
BEVFormer: Learning Bird’s-Eye-View Representation from Multi-Camera Images via Spatiotemporal Transformers 目录 摘要1 介绍2 相关工作2.1 基于Transformer的2D感知 摘要 3D视觉感知任务对于自动驾驶系统至关重要,包括基于多相机图像的3D检测和地图分割。…...
sql专题 之 sql的执行顺序
文章目录 sql的执行顺序sql语句的格式实际的执行顺序:虚拟表 vs 数据集虚拟表 结果集总结嵌套查询在sql查询中的执行顺序 前文我们了解了sql常用的语句,这次我们对于这些语句来个小思索 戳这里→ sql专题 之 常用命令 sql的执行顺序 SQL语句的执行顺序是…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...