En el área de la lógica matemática y la informática conocida como teoría de tipos , un tipo de unidad es un tipo que solo permite un valor (y, por lo tanto, no puede contener información). El portador (conjunto subyacente) asociado con un tipo de unidad puede ser cualquier conjunto singleton . Existe un isomorfismo entre dos conjuntos de este tipo, por lo que es habitual hablar sobre el tipo de unidad e ignorar los detalles de su valor. También se puede considerar el tipo de unidad como el tipo de tuplas 0 , es decir, el producto de ningún tipo.
El tipo de unidad es el objeto terminal en la categoría de tipos y funciones tipificadas. No debe confundirse con el tipo cero o vacío, que no permite valores y es el objeto inicial en esta categoría. De manera similar, el tipo booleano es el tipo con dos valores.
El tipo de unidad se implementa en la mayoría de los lenguajes de programación funcional . El tipo void que se utiliza en algunos lenguajes de programación imperativa cumple algunas de sus funciones, pero debido a que su conjunto de portadores está vacío, tiene algunas limitaciones (como se detalla a continuación).
Varios lenguajes de programación informática proporcionan un tipo de unidad para especificar el tipo de resultado de una función con el único propósito de causar un efecto secundario y el tipo de argumento de una función que no requiere argumentos.
()
y su único valor también es ()
, lo que refleja la interpretación de tupla 0.unit
pero el valor se escribe como ()
.Unit
y su único valor se escribe como ()
.NoneType
que permite el valor único de None
. En las anotaciones de tipo estático opcionales de Python, este tipo se representa como None
. [1]Void
o ()
y su único valor también es ()
, lo que refleja la interpretación de tupla 0.Void
y su único valor es null
.struct{}
y su valor es struct{}{}
.Null
(su único valor es null
) como Undefined
(su único valor es undefined
) son tipos de unidad integrados.Unit
es un singleton con un solo valor: el Unit
objeto.nil
es la única instancia de la NilClass
clase.std::monostate
tipo de unidad se agregó en C++17. Antes de eso, era posible definir un tipo de unidad personalizado usando una estructura vacía como struct empty{}
.En C , C++ , C# , D y PHP , void
se utiliza para designar una función que no devuelve nada útil o una función que no acepta argumentos. El tipo de unidad en C es conceptualmente similar a un vacío struct
, pero una estructura sin miembros no está permitida en la especificación del lenguaje C (esto está permitido en C++). En su lugar, ' void
' se utiliza de una manera que simula algunas, pero no todas, las propiedades del tipo de unidad, como se detalla a continuación. Como la mayoría de los lenguajes imperativos, C permite funciones que no devuelven un valor; estas se especifican como que tienen el tipo de retorno vacío. Dichas funciones se denominan procedimientos en otros lenguajes imperativos como Pascal , donde se realiza una distinción sintáctica, en lugar de una distinción de sistema de tipos, entre funciones y procedimientos.
La primera diferencia notable entre un tipo de unidad verdadero y el tipo void es que el tipo de unidad siempre puede ser el tipo del argumento de una función, pero el tipo void no puede ser el tipo de un argumento en C, a pesar del hecho de que puede aparecer como el único argumento en la lista. Este problema se ilustra mejor con el siguiente programa, que es un error de tiempo de compilación en C:
vacío f ( vacío ) {} vacío g ( vacío ) {} int main ( void ) { f ( g ()); // error de tiempo de compilación aquí devuelve 0 ; }
Este problema no se presenta en la mayoría de las prácticas de programación en C, porque como el void
tipo no lleva información, es inútil pasarlo de todos modos; pero puede surgir en la programación genérica , como las plantillas de C++ , donde void
deben tratarse de manera diferente a otros tipos. Sin embargo, en C++, se permiten las clases vacías, por lo que es posible implementar un tipo de unidad real; el ejemplo anterior se puede compilar como:
clase tipo_unidad {}; const tipo_unidad la_unidad ; tipo_unidad f ( tipo_unidad ) { devuelve la_unidad ; } tipo_unidad g ( tipo_unidad ) { devuelve la_unidad ; } int main () { f ( g ( la_unidad )); return 0 ; }
(Para abreviar, en el ejemplo anterior no nos preocupa si the_unit
es realmente un singleton ; consulte el patrón singleton para obtener detalles sobre ese tema).
La segunda diferencia notable es que el tipo void es especial y nunca se puede almacenar en un tipo de registro , es decir, en una estructura o una clase en C/C++. Por el contrario, el tipo de unidad se puede almacenar en registros en lenguajes de programación funcional, es decir, puede aparecer como el tipo de un campo; la implementación anterior del tipo de unidad en C++ también se puede almacenar. Si bien esto puede parecer una característica inútil, permite, por ejemplo, implementar elegantemente un conjunto como un mapa al tipo de unidad; en ausencia de un tipo de unidad, aún se puede implementar un conjunto de esta manera almacenando algún valor ficticio de otro tipo para cada clave.
En los genéricos de Java, los parámetros de tipo deben ser tipos de referencia. El tipo contenedor Void
se utiliza a menudo cuando se necesita un parámetro de tipo de unidad. Aunque el Void
tipo nunca puede tener ninguna instancia, sí tiene un valor null
(como todos los demás tipos de referencia), por lo que actúa como un tipo de unidad. En la práctica, cualquier otro tipo no instanciable, por ejemplo Math
, también se puede utilizar para este propósito, ya que también tienen exactamente un valor null
.
público estático void f ( void x ) { devuelve null ; } público estático void g ( void x ) { devuelve null ; } public static void main ( String [] args ) { f ( g ( null )); }
Los lenguajes con tipado estático asignan un tipo a cada expresión posible. Deben asociar un tipo a la expresión nula . Se definirá un tipo para la expresión nula y solo tendrá este valor.
Por ejemplo, en D, es posible declarar funciones que solo pueden devolver null :
typeof ( null ) devuelve EsaCosaEspecial (){ devuelve null ; }
null es el único valor que typeof(null) , un tipo de unidad, puede tener.