当前位置: 首页 > news >正文

闲聊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类型,没有什么能够阻止我们放布尔类型,如truefalse,或其他任何类型。另外一个问题是使用困难,因为没有类型,使用前必须进行类型判断和类型转换,如下代码:

 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分门别类,语义清晰,使用容易,孰优孰劣,一目了然。

相信更多的人会问,把DoubleString放到一个数组中有什么实际意义吗?确实没有什么实际意义,但却可以揭示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语言也不例外。但和其他语言相比&#xf…...

抓取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 演员几何 我们已经看到了光照属性如何控制演员的外观&#xff0c;以及相机如何结合变换矩阵将演员投影到图像平面上。剩下的是定义演员的几何形状&#xff0c;以及如何将其定位在世界坐标系中。 建模 计算机图形学研究中的一个重要主题是建模或表示物体的几何形状。…...

pytorch 函数整理

pytorch 函数整理 method_code.init.code.co_argcount&#xff1a;获取method_code.init 函数的输入变量的数目&#xff1b; input_params method_code.init.code.co_varnames&#xff1a;获取method_code.init 函数的输入变量的名称列表&#xff1b; __enter__和__exit__魔…...

docker实战之制作filebeat镜像

一&#xff0c;下载filebeat-6.5.4安装包&#xff1a; https://www.elastic.c o/downloads/beats 二&#xff0c;拉取centos:7镜像 docker pull centos:7 三&#xff0c;将下载的filebeat包放在~/filebeat下&#xff08;自定义就好&#xff09; 四&#xff0c;创建名为fileb…...

【DAY11 软考中级备考笔记】数据结构 查找和排序

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

华为机考:HJ102 字符统计

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

安装配置HBase

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

【更新】数字金融与企业ESG表现:效应、机制与“漂绿”检验数据集(2011-2022年)

参照温亚东&#xff08;2024&#xff09;的做法&#xff0c;本团队对来自统计与决策《数字金融与企业ESG表现&#xff1a;效应、机制与"漂绿"检验》一文中的基准回归部分进行复刻 一、数据介绍 数据名称&#xff1a;数字金融与企业ESG表现 参考期刊&#xff1a;《统…...

手写简易操作系统(五)--获得物理内存容量

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

机器学习之DeepSequence软件使用学习3-预测突变效应

import theano import numpy as np import sys import pandas as pd import scipy #scipy 模块是 Python 中用于科学计算和数据分析的重要模块之一。它包含了许多高级的数学函数和工具&#xff0c;包括数值积分、优化、线性代数、统计等。 from scipy.stats import spearmanr #…...

Linux文件与文件系统的压缩

文章目录 Linux文件与文件系统的压缩Linux系统常见的压缩命令gzip&#xff0c;zcat/zmore/zless/zgrepbzip2&#xff0c;bzcat/bzmore/bzless/bzgreppxz&#xff0c;xzcat/xzmore/xzless/xzgrepgzip&#xff0c;bzip2&#xff0c;xz压缩时间对比打包命令&#xff1a;tar打包命令…...

ubuntu 中进入python 编辑如何退出到命令行

文章目录 在Python解释器&#xff08;交互式命令行&#xff09;中&#xff0c;你可以使用 exit()函数或 CtrlD&#xff08;在Unix/Linux/macOS上&#xff09;或 CtrlZ然后输入 Enter&#xff08;在Windows上&#xff09;来退出Python解释器并返回到命令行。 以下是具体的步骤&a…...

2024.3.12 C++

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

飞塔防火墙开局百篇——002.FortiGate上网配置——透明模式配置(Transparent)

透明模式配置 开启透明模式创建策略 在不改变现有网络拓扑前提下&#xff0c;将防火墙NGFW以透明模式部署到网络中&#xff0c;放在路由器和交换机之间&#xff0c;防火墙为透明模式&#xff0c;对内网网段192.168.1.0/24的上网进行4~7层的安全防护。 登陆FortiGate防火墙界面&…...

代码随想录算法训练营第52天|300.最长递增子序列 674.最长连续递增序列 718.最长重复子数组

300.最长递增子序列 这道题还挺简单的&#xff0c;咱们设置dp[i]表示到第i个数字时的递增子序列的最长的值&#xff0c;那么dp[i]就要遍历从0到i-1的数&#xff0c;也就是看看当前这个数字是否比前面的数字大&#xff0c;如果大的话就看看现在的子序列长度是否会长于前面那个数…...

分享一些开源的游戏仓库

1.CnC_Remastered_Collection 红色警戒95版本 https://github.com/electronicarts/CnC_Remastered_Collection gitee仓库分流&#xff1a;https://gitee.com/loswdarmy/CnC_Remastered_Collection 2.Far-Cry-1-Source-Full 孤岛惊魂1 https://github.com/StrongPC123/Far-Cry-…...

Java详解:单列 | 双列集合 | Collections类

○ 前言&#xff1a; 在开发实践中&#xff0c;我们需要一些能够动态增长长度的容器来保存我们的数据&#xff0c;java中为了解决数据存储单一的情况&#xff0c;java中就提供了不同结构的集合类&#xff0c;可以让我们根据不同的场景进行数据存储的选择&#xff0c;如Java中提…...

Centos7 使用docker来部署mondb

参考官方手册&#xff1a; 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…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

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"…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...