单元类型简介
编辑在被称为类型理论的数理逻辑和计算机科学领域,单元类型是一种只允许一个值的类型。与单位类型相关的载体(底层集合)可以是任何单子集。任何两个这样的集合之间都有一个同构性,所以习惯上我们谈论单位类型而忽略其值的细节。我们也可以把单位类型看作是0-元组的类型,即没有类型的乘积。单位类型是类型和类型化函数类别中的终端对象。它不应与零或底层类型相混淆,后者不允许有任何值,是这个类别中的初始对象。同样地,布尔类型是有两个值的类型。单位类型在大多数函数式编程语言中都有实现。在一些命令式编程语言中使用的void类型可以实现它的一些功能,但是由于它的载体集是空的,所以它有一些限制。
在编程语言中
编辑一些计算机编程语言提供了一个单元类型,用于指定具有xxx目的是引起副作用的函数的结果类型,以及不需要参数的函数的论据类型。在Haskell、Rust和Elm中,单元类型被称为(),其xxx的值也是(),反映了0-tuple的解释。在ML的后代(包括OCaml、StandardML和F#)中,该类型被称为单元,但其值被写成()。在Scala中,单元类型被称为单元,其xxx的值被写成()。在CommonLisp中,名为NULL的类型是一个单元类型,它有一个值,即符号NIL。这不应与NIL类型混淆,后者是底层类型。在Python中,有一种类型叫做NoneType,它允许None的单一值。在Swift中,单元类型叫做Void或(),它的xxx值也是(),反映了0-tuple的解释。在Java中,单元类型叫做Void,它的xxx值是null。在Go中,单元类型写成struct{},其值是struct{}{}。在PHP中,单元类型叫做null,其xxx值是NULL自身。在JavaScript中,Null(其xxx的值是null)和Undefined(其xxx的值是undefined)都是内置的单元类型。在Kotlin中,Unit是一个只有一个值的单子:Unit对象。在Ruby中,nil是NilClass类的xxx实例。
在C++中,std::monostate单元类型在C++17中被添加。在此之前,可以使用一个空的结构来定义一个自定义的单元类型,如structempty{}。Void类型作为单元类型在C、C++、C#和D中,void用来指定一个不返回任何有用的东西的函数,或者一个不接受任何参数的函数。C语言中的单元类型在概念上类似于空结构,但C语言规范中不允许没有成员的结构(C++中允许)。相反,"void"的使用方式模拟了单元类型的一些属性,但不是全部,详见下文。像大多数命令式语言一样,C语言允许不返回值的函数;这些函数被指定为具有void返回类型。这样的函数在其他命令式语言(如Pascal)中被称为过程,在这些语言中,函数和过程之间有语法上的区别,而不是类型系统上的区别。
调用惯例的区别
编辑真正的单元类型和无效类型之间的xxx个显著区别是,单元类型可以一直作为函数的参数类型,但无效类型在C语言中不能作为参数的类型,尽管它可以作为列表中的xxx参数出现。下面的程序最能说明这个问题,它是C语言的一个编译时错误。
这个问题在大多数C语言的编程实践中不会出现,因为空类型不携带任何信息,所以无论如何传递都是无用的;但在通用编程中可能会出现,比如C++模板,在这种情况下,必须将空与其他类型区别对待。然而在C++中,允许空的类,所以有可能实现一个真正的单元类型;上面的例子变成了可编译的。(为了简洁起见,我们在上面的例子中并不担心the_unit是否真的是一个单子;关于这个问题的细节,请看单子模式)。
存储方面的区别
编辑第二个明显的区别是,void类型是特殊的,永远不能存储在记录类型中,即C/C++中的结构或类中。相比之下,单元类型可以存储在函数式编程语言的记录中,即它可以作为字段的类型出现;上述C++中单元类型的实现也可以存储。
内容由匿名用户提供,本内容不代表vibaike.com立场,内容投诉举报请联系vibaike.com客服。如若转载,请注明出处:https://vibaike.com/170892/