编程与类型系统
上QQ阅读APP看书,第一时间看更新

2.1.2 单元类型

在2.1.1节,我们介绍了从不返回的函数。有没有确实会返回,但是不返回任何有意义的值的函数呢?有,并且有许多。我们调用这样的函数只是为了获得它们的副作用:这些函数会执行某些操作,修改一些外部状态,但不会执行有意义的计算来返回给我们。

console.log()为例:它将实参输出到调试控制台,但是不会返回有意义的值。另外,这个函数在执行结束后,会把控制权返回给调用函数,所以它的返回类型不能为never

程序清单2.3中的函数输出了经典的“Hello world!”,这是另外一个很好的例子。我们调用它来输出一句问候(这是一种副作用),而不是返回值,所以我们将其返回类型指定为void

程序清单2.3 一个“Hello world!”的实现函数

这种函数的返回类型叫作单元类型。单元类型只允许有一个值,并且其名称在TypeScript和多数语言中都是void。我们通常不会创建void类型的变量,而是可以直接从一个void函数返回,并不需要先提供一个实际的值,这是因为单元类型的值并不重要。

单元类型:单元类型是只有一个可能值的类型。对于这种类型的变量,检查其值是没有意义的,它只能是那一个值。当函数的结果没有意义时,我们会使用单元类型。

函数可以接受任意数量的实参,但不返回任何有意义的值。这种函数也叫作动作(因为它们通常会执行一个或多个改变状态的操作)或消费者(因为实参进入了函数,但函数不输出任何值)。

自制单元类型

虽然大多数编程语言中都提供了void这样的类型,但是一些语言对void进行了特殊处理,不允许像使用其他类型那样使用void。在这种情况下,通过定义一个枚举,使其只有一个元素,或者定义一个没有状态的单例,可以创建自己的单元类型。因为单元类型只有一个可能的取值,所以这个值是什么其实并不重要;所有单元类型都是相等的。将一个单元类型转换为另一个单元类型并没有太大意义,因为只存在一个选项:一个类型的单个值映射到另一个类型的单个值。

程序清单2.4展示了在TypeScript中如何实现一个单元类型。与自制空类型的示例一样,我们使用了一个void属性,确保其他具有兼容结构的类型不会被隐式转换为Unit。Java和C#等其他语言不需要这个额外的属性。

程序清单2.4 将单元类型实现为一个无状态的单例