Tag: 撰写

Swift中的面向铁路的编程

在本文中,我们将讨论处理函数执行的两个轨道:快乐路径和错误路径。 几乎每个编程任务都由两个用户的轨迹或路径组成。 当一切顺利时,我们称其为“幸福之路”。 但是每次发生某些事情时,尤其是在移动应用程序中。 验证错误,互联网消失,系统杀死我们的应用程序,硬件报告错误,服务器不可用等。 通常,错误路径需要付出更大的努力。 我们应该以某种方式处理所有预期的和意外的错误。 铁路定向编程(ROP)可以帮助我们完成此例程。 该术语的最初发明者是Scott Wlaschin。 他是https://fsharpforfunandprofit.com/的创建者,并且是《 Domain Modeling Made Functional》一书的作者(强烈推荐给所有人)。 在他很少使用F#语言讨论ROP之后,许多社区开始对所有其他语言(而不仅仅是功能语言)采用这种方法。 现在,我想展示一下我们如何在Swift中做到这一点。 让我们从问题开始。 假设我们有一项添加基本用户注册功能的任务。 用户必须提供电子邮件和密码,它们必须有效,并且系统中不应有任何重复的电子邮件。 好的,让我们为注册功能建模。 我们为输入数据和用户创建简单的结构。 CustomDebugStringConvertible协议将有助于打印输出,而UserError枚举描述了注册过程中所有预期的和意外的错误。 这非常简单明了,让我们继续。 验证之后,我们希望将用户保存到数据库或将其发布到Web服务。 再次,为简单起见,我决定使用一个模拟保存到数据库的函数。 在saveToDb(_ 🙂函数中,我们尝试创建新用户并将其放入商店,并在发现重复的情况下引发错误。 好,准备完毕。 现在让我们做第一个尝试编写寄存器功能的尝试。 首先,让我们看一下签名(UserInput)引发-> User。 我们希望接收输入并返回一个新用户。 但是我们也想以某种方式返回所有可能的错误。 一种方法是抛出错误 。 但是通常抛出错误意味着意想不到的事情刚刚发生。 我们期望电子邮件可能无效吗? 是。 我们期望密码可能无效吗? 是。 我们是否期望可能已经存在具有相同电子邮件的用户。 是。 那么,为什么不只将用户和预期错误之一一起返回呢? 人们称这种类型为元组。 Swift可能支持元组。 新的签名是(UserInput)->(User ?, UserError?) 更好,但是现在我们必须对User和UserError使用Optionals 。 这是因为我们可以返回用户或错误,但不能同时返回两者。 熟悉函数式编程的人可以说:“我们在这里需要求和类型!”。 他们将是正确的。 而且我们不必发明新的东西,为此已经存在良好的抽象。 […]