Swift 和 Python 两种语言中带关联信息错误(异常)类型的比较

在这里插入图片描述

0. 概览

如果我们分别在平静如水、和谐感人的 Swift 和 Python 社区抛出诸如“Python 是天下最好的语言…” 和 “Swift 是宇宙第一语言…”之类的言论会有怎样的“下场”?

我们并不想对可能发生的“炸裂”景象做出什么预测,也无意比较 Swift 与 Python 的孰强孰弱。我们只是想聊聊 Swift 和 Python 语言中一个非常有趣的话题:看看谁实现带关联信息的错误(异常)类型更优雅?

在本篇博文中,您将了解到如下内容:

  • 0. 概览
  • 1. “抛出?还是不抛出错误?这是个问题!”
  • 2. 带关联信息的错误
  • 3. Python 中的实现
  • 4. Swift 中实现
  • 5. 那么问题来了:谁更优雅呢?
  • 总结

还等什么呢?Let’s go!!!😉


1. “抛出?还是不抛出错误?这是个问题!”

在秃头码农们辛勤操劳的每一天都会遇到多如牛毛的代码错误,俗话说得好:“事无常形,人无完人”,没有错误的代码只能是还没有写出来的代码。

所幸的是几乎所有语言均对错误做出了良好和友善的支持,Swift 与 Python 自然也不例外!

在 Swift 中我们把代码能够抛出的某种“不安分”的东东称为错误(Error),而在 Python 中这被称之为异常(Exception)。其实从这种意义上来说它们是同一种东西,所以在本篇博文中统统称之为错误

当函数或方法出现“不按常理出牌”的结果时,我们就有必要抛出一个错误。比如除以零:

enum AppError: Error {case divisionByZero
}func div(dividend: Int, divisor: Int) throws -> Int {guard divisor != 0 else {throw AppError.divisionByZero}return dividend / divisor
}

上面是 Swift 中对此的一个实现,在 Python 中有类似的表达:

class DivisionByZero(Exception):passdef div(dividend, divisor):if divisor == 0:raise DivisionByZero()return dividend / divisor

2. 带关联信息的错误

在某些情况下,我们希望抛出的错误中携带一些有用的信息,这种错误称之为:带关联信息的错误

比如当用户输入的文本太短不符合要求时,我们希望进一步了解到用户输入文本的实际长度以及最短需要的长度。

在 Swift 中我们可以通过枚举关联类型来实现带关联信息的错误,类似的在 Python 中我们可以用异常类的附加实例属性来达到这一相同目的。


关于更多 Swift 中枚举使用的奥秘,请小伙伴们移步我的专题视频观看:

  • Swift 基本功修炼:深入浅出 Swift 中的枚举类型

如果小伙伴们还想进一步学习 Swift 语言的开发技巧,可以到我的专题专栏中继续研究:

  • Swift 语言开发精讲(文章平均质量分 97)

下面我们就来分别看看它们的实现吧!

3. Python 中的实现

在这里插入图片描述

在 Python 中可以简单的为自定义异常类增加实例属性变量:

class TextTooShortException(Exception):def __init__(self, actual, min):super().__init__(self)self.actual = actualself.min = minMIN_LEN = 3try:text = "wo"if len(text) < MIN_LEN:raise TextTooShortException(len(text), MIN_LEN)
except TextTooShortException as error:print("错误:文本太短({}),希望不小于 {} 个字符!".format(len(text), MIN_LEN))

如上代码所示,我们创建了一个自定义异常类 TextTooShortException,其中分别用 actual 和 min 实例属性变量来存放输入文本实际和最短所需的长度。

我们看看运行结果:

在这里插入图片描述

4. Swift 中实现

在这里插入图片描述

在 Swift 中对于错误这种不需要实例化的对象,一般可以用枚举来表示(当然也可以用 struct,这要分情况而定)。

对于带关联信息的错误,我们只需要创建带关联类型的枚举元素即可:

enum MyError: Error {case textTooShort(actual: Int, min: Int)
}let text = "wo"do {if text.count < MIN_LEN {throw MyError.textTooShort(actual: text.count, min: MIN_LEN)}
} catch let my_error as MyError {if case MyError.textTooShort(let actual, let min) = my_error {print("输入文字长度(\(actual))太短了,不能小于(\(min))")} else {print("其它 MyError: \(my_error)")}
} catch {print("Other ERR: \(error)")
}

在上面的代码中,我们创建了一个 MyError 类型的错误,并添加了一个 textTooShort 枚举子项。其中我们为其嵌入了两个 Int 值作为关联类型,分别用来表示 actual 和 min 值。

以下是 Playground 中的运行结果:

在这里插入图片描述

5. 那么问题来了:谁更优雅呢?

看过上面两种实现,各位小伙伴们可能都会有自己的考量。

在 Swift 中使用类似于命名元组的枚举关联类型,显得更轻量级。表达 Error 这一概念无需动用 Class 这一重型武器,一个简单的值类型(enum)足以!

在 Python 中的实现也很简单,不过使用类来作为异常的载体显得更加“厚重”,更加中规中矩。

平心而论:Python 在捕获并处理异常时更加简洁,而 Swift 在定义错误时更轻量级,可惜关联类型枚举在错误解析时比较拖垮。

不过,谁说在 Swift 中不能用 Python 的方式自定义错误呢?😉

struct TextTooShortError: Error {var actual: Intvar min: Int
}let text = "wo"do {if text.count < MIN_LEN {throw TextTooShortError(actual: text.count, min: MIN_LEN)}
} catch let tooShortError as TextTooShortError {print("输入文字长度(\(tooShortError.actual))太短了,不能小于(\(tooShortError.min))")
} catch {print("Other ERR: \(error)")
}

总结

在本篇博文中,我们讨论了在 Swift 和 Python 两种语言中对于带关联信息的错误(异常)类型是如何实现的这一话题,并对哪种实现更优雅给出笔者自己的感悟。

感谢观赏,再会!😎

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

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

相关文章

安吉寻梦桃花原

安吉——西湖边的那片竹海 安吉县&#xff0c;地处浙江西北部&#xff0c;湖州市辖县之一&#xff0c;北靠天目山&#xff0c;面向沪宁杭。建县于公元185年&#xff0c;县名出自《诗经》“安且吉兮”之意。 安吉县生态环境优美宜居&#xff0c;境内“七山一水二分田”&#xf…

Java锁常见面试题

图片引用自&#xff1a;不可不说的Java“锁”事 - 美团技术团队 1 java内存模型 java内存模型(JMM)是线程间通信的控制机制。JMM定义了主内存和线程之间抽象关系。线程之间的共享变量存储在主内存中&#xff0c;每个线程都有一个私有的本地内存&#xff0c;本地内存中存储了该…

AI:59-基于深度学习的行人重识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

SOEM源码解析——ecx_init_context(初始化句柄)

0 工具准备 1.SOEM-master-1.4.0源码1 ecx_init_context函数总览 /*** brief 初始化句柄* param context 句柄*/ void ecx_init_context(ecx_contextt *context) {int lp;*(context->slavecount) 0;/* clean ec_slave array *//* 清空从站信息数组 */memset(context->…

win10设置windows永不更新

以下方法能全部设置都要全部设置。 方法一&#xff1a;Windows设置 要想关闭Win10自动更新&#xff0c;比较简单的一种方法就是进入到Windows设置中&#xff0c;将Windows更新直接关闭。步骤如下&#xff1a; 1、按“Windows I”键&#xff0c;打开Windows设置&#xff0c;再…

服务器数据恢复—Zfs文件系统下文件被误删除的如何恢复数据?

服务器故障&#xff1a; 一台zfs文件系统服务器&#xff0c;管理员误操作删除服务器上的数据。 服务器数据恢复过程&#xff1a; 1、将故障服务器所有磁盘编号后取出&#xff0c;硬件工程师检测所有硬盘后没有发现有磁盘存在硬件故障。以只读方式将全部磁盘做扇区级别的镜像备…

gcc -static 在centos stream8 和centos stream9中运行报错的解决办法

gcc -static 在centos stream8 和centos stream9中运行报错的解决办法&#xff1a; 报/usr/bin/ld: cannot find -lc 我们下载glibc-static&#xff1a; 选择x86_64的。 还有一个是libxcrypt-static&#xff0c;依旧在这个网站里搜。 rpm -ivh glibc-static-2.28-239.el8.x…

使用seldom编写http接口用例

在编写接口用例的过程中&#xff0c;针对一个接口&#xff0c;往往只是参数不同&#xff0c;那么参数化就非常有必要了。 seldom 中参数化的用法非常灵活&#xff0c;这里仅介绍file_data() 的N种玩法。 二维列表 当参数比较简单时可以试试下面的方式。 参数化数据 {"…

onnx 模型加载部署运行方式

1.通过文件路径的onnx模型加载方式: 在onnxruntime下面的主要函数:session Ort::Session(env, w_modelPath.c_str(), sessionOptions); 这里的文件路径是宽字节的&#xff0c;通过onnx文件路径直接加载模型。 在opencv下使用dnn加载onnx模型的主要函数: std::string model…

北京联通iptv组播配置

多年前折腾过iptv&#xff0c;近期搬家换了个大电视&#xff0c;打算把iptv配置好了&#xff0c;尽管不怎么看&#xff0c;但聊胜于无。 其实很简单&#xff0c;用到了一些工具&#xff0c;记录如下 1. openwrt配置 因为有软路由&#xff0c;所以就借助openwrt了&#xff0c;一…

【qemu逃逸】HITB2017-babyqemu 2019数字经济-qemu

前言 由于本地环境问题&#xff0c;babyqemu 环境都没有起起&#xff0c;这里仅仅做记录&#xff0c;exp 可能不正确。 HITB2017-babyqemu 设备逆向 设备定位啥的就不说了&#xff0c;先看下实例结构体&#xff1a; 其中 dma_state 结构体如下&#xff1a; 这里看字段猜测…

linux入门到地狱

linux—001入门 IT圈必备(前端工作者用的比较少) 老旧电脑跑linux不容易卡 我代码没保存windows闪退&#xff0c;僵停(vs2019卡掉线)&#xff0c;重启更新,占用cpu内存服务报错pip各种bug 出来生态环境友好其他的全是bug(bug时间成本超过了windows快捷友好生态) 那就说明wind…

ICP学习记录

1. 流程图 ICP&#xff08;一&#xff09;原理详解_icp原理-CSDN博客 ICP算法详解——我见过最清晰的解释-CSDN博客 ICP算法理解-CSDN博客 ICP知识点梳理笔记_icp非凸_KalutSirocco的博客-CSDN博客 【精选】【图像配准】点云配准ICP算法介绍&#xff1a;基础流程、ICP算法…

MyBatis-Plus复习总结(一)

文章目录 一、环境搭键二、基本CRUD2.1 BaseMapper2.2 插入2.3 删除2.4 修改2.5 查询 三、通用Service四、常用注解4.1 雪花算法4.2 注解TableLogic 五、条件构造器和常用接口5.1 Wrapper介绍5.2 QueryWrapper5.3 UpdateWrapper5.4 condition5.5 LambdaQueryWrapper5.6 LambdaU…

Gradle中的依赖Dependencies说明与使用总结

【1】依赖的方式 Gradle 中的依赖分别为直接依赖&#xff0c;项目依赖&#xff0c;本地jar 依赖。 dependencies {//①.依赖当前项目下的某个模块[子工程]implementation project(:subject01)//②.直接依赖本地的某个jar文件implementation files(libs/foo.jar, libs/bar.jar…

行业安卓主板-基于RK3568/3288/3588的电子班牌/人脸识别门禁/室内对讲门禁方案解决方案(二)

电子班牌 智能电子班牌可在主页实时显示班级全面的基本信息&#xff0c;包括天气、班名、课程表、值日表等&#xff0c;并发布学校通知、班级通知。学生可刷卡自动登陆系统进行课堂反馈&#xff0c;教师和家长可及时了解教学反馈&#xff0c;打通学校、教师、学生之间的互动通…

Hive 解析 JSON 字符串数据的实现方式

文章目录 通过方法解析现实示例 通过序列化实现示例 通过方法解析现实 在 Hive 中提供了直接解析 JSON 字符串数据的方法 get_json_object(json_txt, path)&#xff0c;该方法参数解析如下&#xff1a; json_txt&#xff1a;顾名思义&#xff0c;就是 JSON 字符串&#xff1b;…

elasticsearch索引按日期拆分

1.索引拆分原因 如果单个索引数据量过大会导致搜索变慢&#xff0c;而且不方便清理历史数据。 例如日志数据每天量很大&#xff0c;而且需要定期清理以往日志数据。例如原索引为sc_all_system_log&#xff0c;现按天拆分索引sc_all_system_log20220902&#xff0c;sc_all_syste…

B-DS二叉树_输出所有目标路径

Description 给定二叉树和一个整数目标targetSum&#xff0c;输出所有从根结点到叶子结点的路径总和等于targetSun的路径。 Input 第一行输入t&#xff0c;表示有t个测试样例。 第二行起&#xff0c;每一行首先输入一个整数targetSum&#xff0c;接着输入n&#xff0c;接着输…

AMD老电脑超频及性能提升方案及实施

收拾电子元件的时候找到了若干古董的CPU 其中有一个X3 440 是原来同学主板烧了之后给我的&#xff0c;我从网上配了AM2 昂达主板&#xff0c;然后又买了AMD兼容内存&#xff0c;组成了win7 64位电脑&#xff0c;用起来非常不错&#xff0c;我把硬件配置和升级过程说明下&#x…