闲聊Swift的枚举关联值
闲聊Swift的枚举关联值
枚举,字面上理解,就是把东西一件件列出来。 在许多计算机语言中,枚举都是一种重要的数据结构。使用枚举可以使代码更简洁,语义性更强,更加健壮。 Swift语言也不例外。但和其他语言相比,Swift的枚举有一个关联值的概念。什么是关联值呢?关联值是枚举项存放的额外的数据,这些额外的数据可以使枚举描述更复杂的结构 ,实现更复杂的需求。
下面定义了一个枚举,其中的每个枚举项都具有关联值。
enum Progress
{case begin(_ message:String)case progress (_ percent:Double,_ message:String )case end(_ message:String )
}
在上述枚举定义中,begin
项关联了一个类型为String
的值,枚举项表示开始,其关联值进一步表示是什么具体过程。 progress
项关联两个值,一个是百分比,一个是过程本身,枚举项表示进度,关联值则进一步表示是什么任务,到何种进度。有了关联值,我们就可以完整描述一个过程的具体进度了。
关联值看似平淡无奇,实则暗藏玄机。关联值既是Swift枚举不同于其他语言的独特之处,也是Swift枚举之所以强大的基础。
下面我们通过几个小例子简单说明。
问题一:将Double
类型和String
类型的值放到同一个数组中
这个问题好奇怪,为什么会有这样的问题?先不管为什么,先用枚举实现需求再说:
//定义枚举
enum DoubleAndString{case isdouble(_ value:Double)case isstring(_ value:String)}//定义枚举数组let myarr:[DoubleAndString] = [.isdouble(3.14),.isdouble(0.15926),.isstring("两个黄鹂鸣翠柳"),.isdouble(2.718),.isstring("一行白鹭上青天"),.isdouble(0.15926),]//使用数组myarr.forEach{switch $0{case .isdouble (let value):// value 是Double类型,可直接使用print("this is a double item \(value+1)")case .isstring (let value ):print("this is a string item \(value)")}}
可以看到,我们通过定义了一个DoubleAndString
枚举类型及其关联值,很轻易地将Double
类型和String
类型的值存放到一个数组中。
也许你会觉得这个很容易,用Any
数组不是也可以解决吗?如下使用Any
数组的代码,貌似比枚举还简洁一些:
let myarrA:[Any] = [3.14,0.15926,"两个黄鹂鸣翠柳",2.718,"一行白鹭上青天",0.15926,true,false]
但是,它的主要问题是:用Any
数组没有语义。我们可以在这个数组中放Double
类型,也可以放String
类型,但因为是Any
类型,没有什么能够阻止我们放布尔类型,如true
和false
,或其他任何类型。另外一个问题是使用困难,因为没有类型,使用前必须进行类型判断和类型转换,如下代码:
myarrA.forEach{if $0 is Double{//$0 是Any类型,使用前需进行转换let d = $0 as! Double print("double item: \(d+1)")}else{ if $0 is String {print("string item: \($0)") }else{print("bad item: \($0)") }}}
Any
数组是一个巨大的盒子,进去容易出来难。因为它没有分门别类,找起来特别费劲,而且在使用前还得进行类型转换。枚举同样也是一个盒子,但已经按照各种case
分门别类,语义清晰,使用容易,孰优孰劣,一目了然。
相信更多的人会问,把Double
和String
放到一个数组中有什么实际意义吗?确实没有什么实际意义,但却可以揭示Swift枚举的本质:Swift枚举实际上是一个值的容器,我们可以通过它将不同类型的值(关联值)存放到同一个聚合类型(如数组中),并以高度语义化方式使用,这正是许多程序设计需要的非常有用的特性。
问题二:如何给枚举动态增加新的枚举值
Java语言的枚举功能其实也比较强大,可以通过构造函数传入复杂的对象,但有个头痛的问题,枚举项一旦设定,就不能够增加新的项了,因而上述需求在Java语言中无法用枚举实现,只能用普通的类实现,这样就完全不能够享受枚举的便利性了。在Swift中,这样需求可以用枚举直接实现。
比如,我们要对CSDN的文章标签建模,内置标签只有下面几项;如下Swift代码就可以实现:
enum CsdnTag
{case javacase swiftcase mysql
}
但要实现增加自定义标签功能,我们还需要增加一个 custome
枚举项,该枚举项自带一个String类型的关联值,表示自定义的标签,另外,我们还需要增加了一个getTag()
函数,统一将内部标签和自定义标签转换为字符串:
enum CsdnTag
{case javacase swiftcase mysqlcase custome(_ tag:String)func getTag()->String{switch self{case .custome( let tag) :return tagdefault : return "\(self)"}} }
下面是使用枚举的代码:
//定义标签var csdnTags:[CsdnTag] = [.java,.swift,.mysql,//自定义三个标签.custome("python"),.custome("redis"),.custome("vaadin")] //使用标签csdnTags.forEach{print ($0.getTag())}
问题三:如何用枚举简化网络请求。
网络调用的简化的模型如下:
- 调用成功,返回正确的数据
- 调用失败,返回错误信息,包括错误代码,错误信息
根据上面这两种情况,我们直接定义如下枚举:
enum NetResult
{case success (_ data :String )case error(_ errorCode:Int,_ errorString:String)
}
可以看到,建模过程是直截了当的,这是使用枚举的最大优势。
以NetResult
为基础,我们设计网络调用函数如下:
func fetchData(strUrl:String,resultHandler:(NetResult)->Void)
{//网络调用处理//网络调用完成,处理调用结果,假设调用成功var isSuccess = falseif isSuccess {resultHandler(.success("这里是网络调用返回的数据"))}else{resultHandler(.error(202,"非法地址"))}
}
使用上述调用:
fetchData(strUrl:"www.blog.csdn"){ result inswitch result{case .success(let data) : print ("data is:\(data)")case .error (let errorCode,let errorString):print("Network error:errorCode=\(errorCode),errorString=\(errorString)")}}
读者可以思考一下不使用枚举时该如何处理网络调用?无论如何设计,一定都比上述枚举方法繁琐许多。
小结
西方有一句谚语:拿起锤子,看什么都是钉子
。枚举就是Swift语言中的锤子。小伙伴们,赶紧回家拿起你的锤子吧…
相关文章:
闲聊Swift的枚举关联值
闲聊Swift的枚举关联值 枚举,字面上理解,就是把东西一件件列出来。 在许多计算机语言中,枚举都是一种重要的数据结构。使用枚举可以使代码更简洁,语义性更强,更加健壮。 Swift语言也不例外。但和其他语言相比…...

抓取Instagram数据:Fizzler库带您进入C#爬虫程序的世界
引言 在当今数字化的世界中,数据是无价之宝。社交媒体平台如Instagram成为了用户分享照片、视频和故事的热门场所。作为开发人员,我们可以利用爬虫技术来抓取这些平台上的数据,进行分析、挖掘和应用。本文将介绍如何使用C#编写一个简单的Ins…...

Codeforces Round 933 (Div. 3) A~D
比赛链接 : codeforces.com/contest/1941 A . Rudolf and the Ticket 直接暴力即可 ; #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \n #define lowbit(x) (x&(-x)) #define sz(a) (int)a.size() #define p…...

《vtk9 book》 官方web版 第3章 - 计算机图形基础 (3 / 5)
3.8 演员几何 我们已经看到了光照属性如何控制演员的外观,以及相机如何结合变换矩阵将演员投影到图像平面上。剩下的是定义演员的几何形状,以及如何将其定位在世界坐标系中。 建模 计算机图形学研究中的一个重要主题是建模或表示物体的几何形状。…...
pytorch 函数整理
pytorch 函数整理 method_code.init.code.co_argcount:获取method_code.init 函数的输入变量的数目; input_params method_code.init.code.co_varnames:获取method_code.init 函数的输入变量的名称列表; __enter__和__exit__魔…...
docker实战之制作filebeat镜像
一,下载filebeat-6.5.4安装包: https://www.elastic.c o/downloads/beats 二,拉取centos:7镜像 docker pull centos:7 三,将下载的filebeat包放在~/filebeat下(自定义就好) 四,创建名为fileb…...

【DAY11 软考中级备考笔记】数据结构 查找和排序
数据结构 查找和排序 3月12日 – 天气:晴 1. 顺序查找 顺序查找就是简单的从头一个一个的进行比较,注意它的平均查找长度 2. 折半查找 折半查找和二叉排序树一致: 优点:查找效率很高 缺点:要求必须是循序存储并且表中…...

华为机考:HJ102 字符统计
华为机考:HJ102 字符统计 描述 方法1 先将所有字符计算数量,在对比其中字符的assic码 #include<iostream> #include<vector> #include<algorithm> #include<string> using namespace std; bool cmp(pair<char, int> a,…...

安装配置HBase
HBase集群需要整个集群所有节点安装的HBase版本保持一致,并且拥有相同的配置,具体配置步骤如下: 1. 解压缩HBase的压缩包 2. 配置HBase的环境变量 3. 修改HBase的配置文件,HBase的配置文件存放在HBase安装目录下的conf中 4. 首…...

【更新】数字金融与企业ESG表现:效应、机制与“漂绿”检验数据集(2011-2022年)
参照温亚东(2024)的做法,本团队对来自统计与决策《数字金融与企业ESG表现:效应、机制与"漂绿"检验》一文中的基准回归部分进行复刻 一、数据介绍 数据名称:数字金融与企业ESG表现 参考期刊:《统…...

手写简易操作系统(五)--获得物理内存容量
前情提要 上一章中我们进入了保护模式,并且跳转到了32位模式下执行。这一章较为简单,我们来获取物理内存的实际容量。 一、获得内存容量的方式 在Linux中有多种方法获取内存容量,如果一种方法失败,就会试用其他方法。其本质上是…...

机器学习之DeepSequence软件使用学习3-预测突变效应
import theano import numpy as np import sys import pandas as pd import scipy #scipy 模块是 Python 中用于科学计算和数据分析的重要模块之一。它包含了许多高级的数学函数和工具,包括数值积分、优化、线性代数、统计等。 from scipy.stats import spearmanr #…...

Linux文件与文件系统的压缩
文章目录 Linux文件与文件系统的压缩Linux系统常见的压缩命令gzip,zcat/zmore/zless/zgrepbzip2,bzcat/bzmore/bzless/bzgreppxz,xzcat/xzmore/xzless/xzgrepgzip,bzip2,xz压缩时间对比打包命令:tar打包命令…...
ubuntu 中进入python 编辑如何退出到命令行
文章目录 在Python解释器(交互式命令行)中,你可以使用 exit()函数或 CtrlD(在Unix/Linux/macOS上)或 CtrlZ然后输入 Enter(在Windows上)来退出Python解释器并返回到命令行。 以下是具体的步骤&a…...

2024.3.12 C++
1.思维导图 2.自己封装一个矩形类(Rect),拥有私有属性:宽度(width)、高度(height),定义公有成员函数: 初始化函数:void init(int w, int h)更改宽度的函数:set_w(int w)更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show() #include <iostream…...

飞塔防火墙开局百篇——002.FortiGate上网配置——透明模式配置(Transparent)
透明模式配置 开启透明模式创建策略 在不改变现有网络拓扑前提下,将防火墙NGFW以透明模式部署到网络中,放在路由器和交换机之间,防火墙为透明模式,对内网网段192.168.1.0/24的上网进行4~7层的安全防护。 登陆FortiGate防火墙界面&…...
代码随想录算法训练营第52天|300.最长递增子序列 674.最长连续递增序列 718.最长重复子数组
300.最长递增子序列 这道题还挺简单的,咱们设置dp[i]表示到第i个数字时的递增子序列的最长的值,那么dp[i]就要遍历从0到i-1的数,也就是看看当前这个数字是否比前面的数字大,如果大的话就看看现在的子序列长度是否会长于前面那个数…...
分享一些开源的游戏仓库
1.CnC_Remastered_Collection 红色警戒95版本 https://github.com/electronicarts/CnC_Remastered_Collection gitee仓库分流:https://gitee.com/loswdarmy/CnC_Remastered_Collection 2.Far-Cry-1-Source-Full 孤岛惊魂1 https://github.com/StrongPC123/Far-Cry-…...

Java详解:单列 | 双列集合 | Collections类
○ 前言: 在开发实践中,我们需要一些能够动态增长长度的容器来保存我们的数据,java中为了解决数据存储单一的情况,java中就提供了不同结构的集合类,可以让我们根据不同的场景进行数据存储的选择,如Java中提…...
Centos7 使用docker来部署mondb
参考官方手册: https://www.mongodb.com/docs/manual/tutorial/install-mongodb-community-with-docker/#std-label-docker-mongodb-community-install 使用脚本快速安装docker curl -fsSL https://get.docker.com -o get-docker.sh | bash get-docker.sh使用 Doc…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...