Swift 入门之自定义类型的模式匹配(Pattern Matching)

在这里插入图片描述

概览

小伙伴们都知道 Swift 是一门简洁、类型安全、极富表现力以及“性感迷人”的编程语言。

和大多数语言一样,在 Swift 中也有一些隐藏着的、不为人知的宝藏特性。利用它们我们可以极大增加撸码的愉悦和成就感。

其中,模式匹配(Pattern Matching)便是如此!征服它,我们的 Swift 开发技能又可以大步迈上一个新的台阶。

在本篇博文中,您将学到以下内容:

  • 概览
  • 1. 什么是模式匹配?
  • 2. 模式匹配符
  • 3. 模式匹配在 switch 语句中的应用
  • 4. 威力大增:模式匹配重载
  • 总结

闲言少叙,让我们马上开始模式匹配的探索之旅吧!

Let’s Go!!!😉


1. 什么是模式匹配?

模式匹配一种让我们可以更简洁更便利的比较、检查和解析数据的方式。

不光在 Swift 语言中,模式匹配的概念在很多其它编程语言中都能大放异彩。

比如,在下面 ruby 代码中我们通过模式匹配快速的检查了正则表达式是否匹配指定的字符串:

irb(main):001:0> r = /[a-z]at/
=> /[a-z]at/irb(main):002:0> r =~ "xat"
=> 0
irb(main):003:0> r =~ "11zat"
=> 2
irb(main):004:0> r =~ "1at"
=> nil

在 Swift 中的模式匹配与此类似,不过它们特别适用于 switch 语句的语境中。

那么 switch 语句如何适配模式匹配呢?答案是:用模式匹配符

2. 模式匹配符

在 Swift 语言中,模式匹配符为 ~=。在内置一些类型上它会退化为 == 操作符的行为:

let string = "hello"
let power = 11if string ~= "hello", power ~= 11 {print("matched!")
}
/* 输出结果为:
matched!
*/

注意,Swift 中匹配符(~=)与 ruby 中(=~)是正好反过来的。

我们可以为任意自定义类型做匹配模式的适配:

struct Foo {static func ~=(pattern: Double, value: Foo) -> Bool {value.size == pattern}var size = CGFloat.zero
}let foo = Foo()
if 0.0 ~= foo {print("matched!")
}
/*
输出结果为:
matched!
*/

这里有两点需要注意:

  1. 匹配模式方法可以定义在类型外面;
  2. 若还要做“逆向”匹配,则我们需要两个匹配方法;

以下是演示代码:

struct Foo {var size = CGFloat.zero
}func ~=(pattern: Double, value: Foo) -> Bool {value.size == pattern
}// 逆向匹配方法
func ~=(value: Foo, pattern: CGFloat) -> Bool {value.size == pattern
}let foo = Foo()
if 0.0 ~= foo {print("matched!")
}// 逆向匹配
if foo ~= 0.0 {print("matched too!")
}
/*输出结果为:
matched!
matched too!
*/

我们还可以对 Swift 标准库中的类型做扩展以支持匹配模式,比如让正则表达式支持 ~= 操作符:

let regex = /[a-z]at/func ~=(pattern: String, value: Regex<Substring>) -> Bool {let result = try? pattern.firstMatch(of: value)return result != nil
}if "11xat" ~= regex {print("matched!")
}
/*输出结果为:
matched!
*/

直接利用 ~= 匹配可以为我们开发带来一定便利,不过更好的 idea 是将其嵌入到 switch 语句中以发挥最大威力。

3. 模式匹配在 switch 语句中的应用

在 Swift 中 switch 语句背后那个“默默无闻的男人”恰好就是模式匹配操作符。

struct Foo {var size = CGFloat.zero
}func ~=(pattern: Double, value: Foo) -> Bool {value.size == pattern
}

对于上面已经抱上模式匹配大腿的 Foo 类型,我们可以直接将其融入到 switch 语句中去:

let foo = Foo()switch(foo) {
case 0:print("ZERO")
case 5:print("FIVE")
default:print("others")
}
/*输出结果:
ZERO
*/

4. 威力大增:模式匹配重载

如果小伙伴们以为这就结束了,那显然大家的格局还要再打开一些。

利用重载机制,我们可以让自定义类型在 switch 语句中的模式匹配更加大放异彩。

比如,如果除了直接比较 Foo#size 属性以外,我们还想判断该属性的值是否在一个范围中,这该如何是好呢?

很简单,我们对模式匹配符进行重载:

func ~=(pattern: ClosedRange<CGFloat>, value: Foo) -> Bool {pattern.contains(value.size)
}

有了上面的定义,现在我们可以在同一个 switch 语句中用两种方式来匹配 Foo 对象的值了:

let foo = Foo(size: 11)switch(foo) {
case 0:print("ZERO")
case 5:print("FIVE")
case 0...11:print("Bingooo!!!")
default:print("others")
}/* 输出结果为:
Bingooo!!!
*/

看到这里,小伙伴们是否都已摩拳擦掌,想在 Swift 中去尝试应用模式匹配更多的“奇思妙想”呢?

勇敢去爱,不畏将来,不念过往。
放手去爱,让爱如风般自由,如光般璀璨。

所以,勇敢的去吧!The brave are invincible!棒棒哒!💯

总结

在本篇博文中,我们讨论了在 Swift 中如何优雅的适配模式匹配,并介绍了如何使用模式匹配操作符重载机制在 switch 语境中让开发“简约而简单”。

感谢观赏,再会!😎

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

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

相关文章

Linux---动静态库

动静态库的相关概念 静态库&#xff08;.a&#xff09;&#xff1a;程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库动态库&#xff08;.so&#xff09;&#xff1a;程序在运行的时候才去链接动态库的代码&#xff0c;多个程序共享使用库的…

2024 年 11 款值得收藏的 iPhone 数据恢复软件和应用

数据丢失是任何人都无法承受的&#xff0c;因为它对每个人都至关重要。但是数据丢失的原因有很多&#xff0c;一些常见的原因是数据意外删除、设备被盗、iOS 越狱、硬件损坏、病毒感染等。我们列出了 iOS 的顶级恢复工具&#xff0c;其中将帮助您方便地恢复数据。 这是 11 款最…

k8s之安装部署及kuboard发布应用

目录 环境准备 系统规划 配置免密 将桥接的IPv4流量传递到iptables的链 系统基础配置 安装docker 安装docker及基础依赖 配置docker的仓库下载地址 部署k8s 添加阿里云的k8s源 安装kubeadm&#xff0c;kubelet和kubectl 初始化masteer节点 部署node节点 部署flanne…

docker相关问题解决(file exists、not a directory

背景 以下环境为wsl file exists 缓存没删干净 docker-compose down -v not a directory flags: 0x5000: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? 明明我确定报错指示的位置就是文件而不是文件夹...相当神奇的错误 …

【C++初阶】--入门基础(二)

目录 一.C输出与输入 二.缺省参数 1.概念 2.缺省参数分类 (1) 全缺省参数 (2)半缺省参数 三.函数重载 1.概念 2.C支持函数重载的原理--名字修饰 四.引用 1.概念 2.语法 3.引用的特性 (1)引用在定义时必须初始化 (2)引用时不能改变指向 (3)一个变量…

UE 代码构建(BuildSystem)与源码编译相关

年底了&#xff0c;把之前的草稿文章整理一下&#xff0c;整理好的发出来 UnrealBuildTool简介 参考&#xff1a;https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/BuildTools/UnrealBuildTool/ UE里的项目代码、包括UE本身的源码&#xff0c;都是划分成一个…

flv视频格式批量截取封面图(不占内存版)--其他视频格式也通用

flv视频格式批量截取封面图&#xff08;不占内存版&#xff09;--其他视频格式也通用 需求&#xff08;实现的效果&#xff09;功能实现htmlcssjs 需求&#xff08;实现的效果&#xff09; 批量显示视频&#xff0c;后端若返回有imgUrl,则直接显示图1&#xff0c; 若无&#xf…

Socket套接字类编译测试

目录 类设计 类实现 测试 测试服务器 测试客户端 测试结果 这一节相当于整合了之前的一些东西&#xff0c;重新过了一遍&#xff0c;这个就显得相对之前的版本更加完善一点 类设计 // 套接字类 #define MAX_LISTEN 1024 class Socket {private:int _sockfd;public:Socke…

闲人闲谈PS之五十三——离散制造中的魔鬼--物料套裁

惯例闲话&#xff1a;最近和老婆大人商议买车事宜&#xff0c;闲人以为会陷入买油车还是电车的纠结&#xff0c;没想到老婆大人无比坚定&#xff0c;买电车。在买车这方面&#xff0c;老婆的想法居然比闲人超前。闲人对车定位在代步工具&#xff0c;2年前&#xff0c;对车还是印…

SAP下载word

事务代码&#xff1a;STRANS 启动转换器 步骤 1. 将参数填入模板&#xff0c;并另存为word 2003 xml文档 2.使用网页打开xml文档&#xff0c;并将xml拷贝到转换器tt:template中&#xff0c;添加参数 3.替换参数&#xff0c;部分xml可能存在错误或者跑偏根据实际情况检查修改 …

洛谷 P1980 [NOIP2013 普及组] 计数问题

题目背景 NOIP2013 普及组 T1 题目描述 试计算在区间 1 到 n 的所有整数中&#xff0c;数字 x&#xff08;0≤x≤9&#xff09;共出现了多少次&#xff1f;例如&#xff0c;在 1 到 11 中&#xff0c;即在 1,2,3,4,5,6,7,8,9,10,11 中&#xff0c;数字 1 出现了 4 次。 输入…

Ubuntu18.04安装Matlab流程笔记

提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 Ubuntu18.04 安装Matlab流程 下载安装包和破解文件安装Matlab注册并运行 下载安装包和破解文件 matlabR2019A源码 提取码:2ztb 下载的Linux matlab2018a文件夹内有三个文件&#xff1a; # 解压Matlab201…

<网络安全>《15 移动安全管理系统》

1 概念 移动安全管理系统&#xff0c;MSM&#xff0c;Mobile security management,提供大而全的功能解决方案&#xff0c;覆盖了企业移动信息化中所涉及到安全沙箱、数据落地保护、威胁防护、设备管理、应用管理、文档管理、身份认证等各个维度。移动安全管理系统将设备管理和…

freeswitch对接FunASR实时语音听写

1、镜像启动 通过下述命令拉取并启动FunASR软件包的docker镜像&#xff1a; sudo docker pull \registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.7 mkdir -p ./funasr-runtime-resources/models sudo docker run -p 10096:10095 -i…

elementUI中el-tree组件单选没有复选框时,选中、current-node-key高亮、刷新后保留展开状态功能的实现

目录 一、代码实现1. 属性了解 &#xff08;[更多](https://element.eleme.cn/#/zh-CN/component/tree)&#xff09;2. 实现步骤3.代码示例 二、 效果图 一、代码实现 1. 属性了解 &#xff08;更多&#xff09; node-key 每个树节点用来作为唯一标识的属性&#xff0c;整棵树…

Linux 磁盘空间占用率100%的排查

&#x1f4d1;前言 使用 Linux 操作系统时&#xff0c;可能会遇到磁盘空间不足的错误&#xff0c;这种错误通常会导致系统运行缓慢或崩溃。本文将介绍磁盘排查的方法。⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1…

rust gui开发框架选择

作为一个系统编程强大语言&#xff0c;怎么能少得了图形界面的开发 实际上写这篇前我也不知道&#xff0c;于是我问了ai大模型&#xff0c;文心3.5和chatgpt4.0 答案实际上不能满意&#xff0c;最后我做了下筛选 参考博文&#xff1a; rust开发环境配置&#xff1a;链接 一、…

MacOS安装JDK+Maven+Idea插件+nvm等

Java安装环境(MacOS)JDKMavenIdea插件nvm等 背景&#xff1a;新机安装开发环境发现需要找很多文章&#xff0c;&#xff0c;&#xff0c;&#xff0c;这里一篇文章安装所有环境 文章目录 Java安装环境(MacOS)JDKMavenIdea插件nvm等一、安装JDK①&#xff1a;下载②&#xff1a;…

阿里云a10GPU,centos7,cuda11.2环境配置

Anaconda3-2022.05-Linux-x86_64.sh gcc升级 centos7升级gcc至8.2_centos7 yum gcc8.2.0-CSDN博客 paddlepaddle python -m pip install paddlepaddle-gpu2.5.1.post112 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html 报错 ImportError: libssl.so…

C++ pair+map+set+multimap+multiset+AVL树+红黑树(深度剖析)

文章目录 1. 前言2. 关联式容器3. pair——键值对4. 树形结构的关联式容器4.1 set4.1.1 set 的介绍4.1.2 set 的使用 4.2 map4.2.1 map 的介绍4.2.2 map 的使用 4.3 multiset4.3.1 multiset 的介绍4.3.2 multiset 的使用 4.4 multimap4.4.1 multimap 的介绍4.4.2 multimap 的使…