Swift中类型安全的标识符

请注意,这个实现使用
**Identifiable**协议,该协议仅在iOS 13+上可用,所以你可以尝试在旧系统上使用一个没有这种特殊一致性的 "剥离 "版本。
问题所在
简单来说,标识符是一连串的字符,对某一特定类型的模型来说是唯一的。
例如,如果你的应用程序中有一个用户模型,并且它有一个ID属性,那么可以保证它的值在一组用户模型中不会出现超过一次。
假设我们正在开发一个社交网络应用,用户可以写帖子并留下评论。他们假设的模型将是。
想象一下,由于某种原因,一方面,用户有String ,另一方面,帖子和评论使用整数ID。再一次--用户没有问题,他们的ID是已知的,是唯一的。
然而,当涉及到其他模式时,就有一些隐患了。不仅一些帖子的ID可以和一些评论的ID相等,我们也实际上能够意外地比较它们。而最大的问题是,编译器不能帮助我们什么。
理想的结果是,只有可能比较兼容的ID。
让我们试着实现这种行为吧!
类型
泛型在Swift中是真正强大的。它们的众多应用之一就是能够将它们作为幻象类型使用。简单地说,当一个类型被声明但没有被任何成员使用时,它就被称为幻影。
它只需要编译器来区分某些容器类型。对一个ID来说,这种容器最简单的实现就是。
有点麻烦,你不觉得吗?这些ID的声明和初始化都太啰嗦了。
我们甚至不得不为每个模型引入一个假的枚举,只是为了使用一个标识符。让我们试着封装一下这个实现吧!
改进的解决方案
首先,应该使用ID类型的嵌套类型别名,这样我们就不必在模型的范围之外知道它的ID类型。
我想只写一些像let post: Post.ID ,而不用担心幕后使用的东西。
第二,也许有办法摆脱虚拟枚举?也许 :)
第三,让我们简化标识符的初始化。由于ExpressibleBy... 协议组,这是很可行的。
奖励:我们可以使我们的模型与SwiftUI的迭代机制兼容,如ForEach ,List ,等等,开箱即用,只需纳入Identifiable 协议。
鉴于上述几点,这里是更新后的实现。
现在,让我们用Swift基本类型的字面符号来表达的能力来加强这个解决方案。
因此,我们可以像下面这样声明我们的模型。
最终,我们的模型可以像这样被使用。

结论
很好!这个实现可以通过Decodable 和其他你可能需要的东西来改进,但这不在本文的讨论范围之内。
谢谢你的阅读!