依赖类型(在Swift中)拯救世界!

依赖类型(有时称为约束类型)使代码更安全,更易于使用。 使用从属类型是最有用和鲜为人知的编程概念之一。 我希望阅读完这篇文章后,您会觉得自己像个机械师,刚刚学会了如何加工自己的零件。

我将提供一些背景知识,然后向您展示依赖类型如何拯救世界。

什么是从属类型?

在计算机科学和逻辑中, 从属类型是其定义取决于值的类型。 “整数对”是一种类型。 由于对值的依赖性,“第二对大于第一对的整数对”是从属类型。 —有关相关类型的维基百科文章

由于在Swift中基本类型和用户类型之间几乎没有区别,因此您很有可能已经使用了依赖类型。

考虑无符号整数类型: UInt

  UInt(正好:1)// 1 
UInt(正好:1.0)// 1
UInt(正好:-1)//无

是否能够创建UInt取决于
a)您传递给初始化程序的值为正,并且
b)可解析为整数的值

使用UInt ,是在传达要处理的正整数的信息。 这是有帮助的。

是时候拯救世界了!

假设我们的工作是为核电厂编写软件。²

如果反应堆过热,则可能引发气候事件并导致地球生命的尽头。 我们需要一个函数来冷却它:

  func addCoolantToNuclearPowerPlant(加仑:整数) 

可能您可以用负数来称呼它:

  func doEmergencyStuff(){ 
addCoolantToNuclearPowerPlant(加仑:-1000000)
}

您已经排干了所有水,并引发了核灾难。 很容易看出为什么UInt类型将是此参数的更安全选择。

  func addCoolantToNuclearPowerPlant(加仑:UInt) 

现在,假设发电厂过热时至少需要一万加仑的冷却液。 在当前的定义中,我们不能偶然排放冷却剂,但是仍然可以将不足量的填料传递给冷却功能。 让我们通过在函数内添加检查来解决此问题,以免意外导致反应堆开销。

您会从检查中注意到,该参数的值存在隐式依赖性。

我们可以并且应该通过定义新的Dependent Type使隐式显式。 我们称它为Coolant

Coolant此定义使用一个可失效的初始化程序来确保除非存在至少一万个Coolant否则它不会存在。 现在,我们可以重新定义冷却功能,如下所示。

现在,除了所需的最小Coolant剂量外,不可能用其他任何方法调用此功能。