迅捷:链式铸造

正如我之前在Swift的类型推断中所提到的。 我真的对在我的代码中各处编写iflet和guard感到厌倦。

Swift中的类型推断
我要坦白。 我真的对在我的代码中各处编写iflet和guard感到厌倦。 有… blog.idapgroup.com

为了概述问题,让我们假设有一个UITableView ,其中我们需要呈现来自不同继承层次结构的UITableViewCell子类:

然后,让我们想象一下,Swift开发团队会使iflet失效。 众所周知,xCode Swift迁移工具并非始终可用,在某些情况下,我们必须手动重写代码。 我在Swift选择器上进行了这样的转换,这对我来说是一个巨大的痛苦。 而且,在我看来,iflets违反了我们所有人都喜欢和崇拜的DRY原则。 非DRY代码在重构或重写方面确实很痛苦,因为您没有集中的访问点。

为了解决这些问题,我更喜欢使用自己的解决方案:

稍后我们将详细介绍实现细节,但是现在让我解释一下,为什么我(不是真的)认为这种解决方案更好:

  • 它使用类型推断;
  • 富有表现力;
  • 它是可扩展的;
  • 它很健壮。

是的,我知道,对于任何不了解它的新手来说,它会使学习曲线更加陡峭。 是的,开关模式匹配也可以做到这一点,尽管语法会更加冗长。 但是它最终提供的是,只要我遵守界面,就可以注入任何我想要的行为,无论Swift如何改变。 当然,如果您愿意使用它,那将最终由您决定。 我绝对喜欢,因为我可以用更少的按键来表达相同的逻辑,并专注于真正重要的东西(我关于我要表达的内容的想法,而不是我要表达的想法)。

那么,它是如何在后台运行的呢?

请阅读我以前有关强制转换功能的文章之一。 为了更大的利益,我将在此处概述其签名,但是您需要知道如何使用它:

我提出的解决方案的实质是基于Castable泛型类型的:

首先,让我们回答一个最明显的问题:“为什么我们要在一种情况下使用switch ? 原因是很简单。 为了让Swift在没有默认返回值的情况下处理这样的表达式,该函数应该是穷举的,除了涵盖所有枚举情况的开关,Swift都认为该函数不是穷举的。 穷举是指处理所有枚举的情况。 此外, 如果case的语法更差:

这将失败,并在预期返回’NonExhaustive ‘的函数中缺少返回错误,并使用默认返回值作为self重写它可以解决问题:

但这只是为了自己的利益而编写的太多代码。

可能会出现的第二个问题是:“它是如何工作的?”

您看,我认为Castable作为一种类型可以通过两种方式进行处理:匹配和提取。

  • 通过匹配,我的意思是强制转换一个包装的值,如果强制转换成功,则使用强制转换的结果调用该函数。 为了能够链接操作,我只返回了另一个包装相同值的Castable
  • 提取只是解包并返回一个值。

从我的观点来看,通过一遍又一遍地重写相同的行来创建Castable不是一个好主意。 试想一下,每次要使用匹配和提取时,都必须编写Castable.value(x).match(…这是最常见的用例,对吗?可悲的是,我们不能只创建一个全局变量函数超出Castable.value初始值设定项,因为Swift不允许泛型使用该函数: let castableFunction = Castable.value导致错误:无法推断出泛型参数“ Wrapped”注意:显式指定泛型参数来解决此问题 。我能说什么Swiftc,你喝醉了,回家。

因此,为了修复该问题,我创建了几个最常用的功能-我认为是这样的情况:

如果您看到任何其他用例,或者只是想添加一些东西,请毫不犹豫地创建拉取请求。

该库可以在cocoapods IDPCastable上找到 ,也可以在github上找到:IDPCastable。 您可以根据需要在Tests / iOS中查看示例。

就是这样,伙计们。 祝您有美好的一天,无论您身在何处,都要保持干燥。