En ciencias de la computación , la conversión de tipos , [ 1 ] [ 2 ] la conversión de tipos , [ 1 ] [ 3 ] la coerción de tipos , [ 3 ] y el juego de tipos [ 4 ] [ 5 ] son diferentes maneras de cambiar una expresión de un tipo de datos a otro. Un ejemplo sería la conversión de un valor entero a un valor de punto flotante o su representación textual como una cadena , y viceversa. Las conversiones de tipos pueden aprovechar ciertas características de las jerarquías de tipos o representaciones de datos . Dos aspectos importantes de una conversión de tipos son si ocurre implícitamente (automáticamente) o explícitamente , [ 1 ] [ 6 ] y si la representación de datos subyacente se convierte de una representación a otra, o si una representación dada simplemente se reinterpreta como la representación de otro tipo de datos. [ 6 ] [ 7 ] En general, tanto los tipos de datos primitivos como los compuestos pueden convertirse.
Cada lenguaje de programación tiene sus propias reglas sobre cómo se pueden convertir los tipos. Los lenguajes con tipado fuerte suelen realizar pocas conversiones implícitas y desaconsejan la reinterpretación de representaciones, mientras que los lenguajes con tipado débil realizan muchas conversiones implícitas entre tipos de datos. Los lenguajes de tipado débil a menudo permiten forzar al compilador a interpretar arbitrariamente un elemento de datos con diferentes representaciones; esto puede ser un error de programación no evidente o un método técnico para interactuar directamente con el hardware subyacente.
En la mayoría de los lenguajes, el término «coerción» se utiliza para denotar una conversión implícita , ya sea durante la compilación o durante la ejecución . Por ejemplo, en una expresión que combina números enteros y de coma flotante (como 5 + 0.1), el compilador convertirá automáticamente la representación entera a coma flotante para que no se pierdan las fracciones. Las conversiones de tipo explícitas se indican escribiendo código adicional (por ejemplo, añadiendo identificadores de tipo o llamando a rutinas integradas ) o codificando rutinas de conversión para que el compilador las utilice cuando, de otro modo, se detendría por una discrepancia de tipos.
En la mayoría de los lenguajes tipo ALGOL , como Pascal , Modula-2 , Ada y Delphi , la conversión y el casting son conceptos claramente distintos. En estos lenguajes, la conversión se refiere al cambio, implícito o explícito, de un valor de un formato de almacenamiento de tipo de datos a otro, por ejemplo, de un entero de 16 bits a uno de 32 bits. Las necesidades de almacenamiento pueden cambiar como resultado de la conversión, incluyendo una posible pérdida de precisión o truncamiento. El término " cast" , por otro lado, se refiere al cambio explícito de la interpretación del patrón de bits que representa un valor de un tipo a otro. Por ejemplo, 32 bits contiguos pueden tratarse como una matriz de 32 booleanos, una cadena de 4 bytes, un entero sin signo de 32 bits o un valor de punto flotante de precisión simple IEEE. Dado que los bits almacenados nunca cambian, el programador debe conocer detalles de bajo nivel, como el formato de representación, el orden de bytes y las necesidades de alineación, para realizar un casting efectivo.
En la familia de lenguajes C y ALGOL 68 , el término «cast» suele referirse a una conversión de tipo explícita (en contraposición a una conversión implícita), lo que genera cierta ambigüedad sobre si se trata de una reinterpretación de un patrón de bits o de una conversión de representación de datos real. Más importante aún es la multitud de métodos y reglas que rigen el tipo de dato (o clase) al que apunta un puntero y cómo el compilador puede ajustar dicho puntero en casos como la herencia de objetos (o clases).
Lanzamiento explícito en varios idiomas
Ada
Ada proporciona una función de biblioteca genérica Unchecked_Conversion. [ 8 ]
Lenguajes similares a C
Conversión de tipo implícita
La conversión implícita de tipos, también conocida como coerción o manipulación de tipos , es una conversión automática de tipos realizada por el compilador . Algunos lenguajes de programación permiten que los compiladores realicen la coerción; otros la requieren.
En una expresión de tipo mixto, los datos de uno o más subtipos se pueden convertir a un supertipo según sea necesario en tiempo de ejecución para que el programa se ejecute correctamente. Por ejemplo, el siguiente es un código válido en lenguaje C :
doble d ; largo l ; entero i ;Si ( d > i ) { d = i ; }Si ( i > l ) { l = i ; }Si ( d == l ) { d *= 2 ; }Aunque d , l e i pertenecen a diferentes tipos de datos, se convertirán automáticamente a tipos de datos iguales cada vez que se ejecute una comparación o asignación. Este comportamiento debe usarse con precaución, ya que pueden surgir consecuencias no deseadas. Se pueden perder datos al convertir representaciones de punto flotante a entero, ya que los componentes fraccionarios de los valores de punto flotante se truncarán (redondearán hacia cero). Por el contrario, se puede perder precisión al convertir representaciones de entero a punto flotante, ya que un tipo de punto flotante puede no ser capaz de representar con exactitud todos los valores posibles de algún tipo de entero. Por ejemplo, podría ser un tipo de precisión simple IEEE 754 , que no puede representar el entero 16777217 con exactitud, mientras que un tipo de entero de 32 bits sí puede. Esto puede dar lugar a un comportamiento poco intuitivo, como se demuestra en el siguiente código:float
#include <stdio.h>int main ( void ) { int my_int = 16777217 ; float my_float = 16777216.0 ; printf ( "El entero es: %d \n " , my_int ); printf ( "El flotante es: %f \n " , my_float ); printf ( "Su igualdad: %d \n " , my_int == my_float ); }En los compiladores que implementan los números de coma flotante como precisión simple IEEE y los enteros como de al menos 32 bits, este código producirá esta peculiar impresión:
El número entero es: 16777217 El valor flotante es: 16777216.000000 Su igualdad: 1
Nótese que 1 representa la igualdad en la última línea. Este comportamiento anómalo se debe a una conversión implícita a i_valuefloat al compararlo con f_value. La conversión provoca una pérdida de precisión, lo que hace que los valores sean iguales antes de la comparación.
Conclusiones importantes:
floatprovocainttruncamiento , es decir, la eliminación de la parte fraccionaria .doubleparafloatprovocar el redondeo del dígito.longparaintprovocar la pérdida de bits de orden superior sobrantes.
Tipo de promoción
Un caso especial de conversión implícita de tipos es la promoción de tipos, donde un objeto se convierte automáticamente a otro tipo de dato que representa un superconjunto del tipo original. Las promociones se utilizan comúnmente con tipos más pequeños que el tipo nativo de la unidad aritmético-lógica (ALU) de la plataforma de destino, antes de las operaciones aritméticas y lógicas, para posibilitar dichas operaciones o hacerlas más eficientes si la ALU puede trabajar con más de un tipo. C y C++ realizan dicha promoción para objetos de tipo booleano, carácter, carácter ancho, enumeración y entero corto, que se promueven a int, y para objetos de tipo float, que se promueven a double. A diferencia de otras conversiones de tipos, las promociones nunca pierden precisión ni modifican el valor almacenado en el objeto.
En Java :
int x = 3 ; double y = 3.5 ; System.out.println ( x + y ) ; // La salida será 6.5Conversión de tipo explícita
La conversión explícita de tipos, también llamada conversión de tipos, es una conversión que se define explícitamente dentro de un programa (en lugar de realizarse automáticamente según las reglas del lenguaje para la conversión implícita de tipos). El usuario la solicita en el programa.
doble a = 3.3 ; doble b = 3.3 ; doble c = 3.4 ;int resultado = static_cast <int> ( a ) + static_cast <int> ( b ) + static_cast <int> ( c ) ; // resultado == 9 // si se utilizara la conversión implícita (como con " resultado = a + b + c"), el resultado sería igual a 10Existen varios tipos de conversión explícita.
- comprobado
- Antes de realizar la conversión, se lleva a cabo una comprobación en tiempo de ejecución para ver si el tipo de destino puede contener el valor de origen. Si no es así, se genera una condición de error.
- desenfrenado
- No se realiza ninguna comprobación. Si el tipo de destino no puede contener el valor de origen, el resultado es indefinido.
- patrón de bits
- La representación bit a bit sin procesar de la fuente se copia textualmente y se reinterpreta según el tipo de destino. Esto también se puede lograr mediante alias .
En los lenguajes de programación orientados a objetos , los objetos también pueden ser convertidos a una clase derivada : una referencia a una clase base se convierte a una de sus clases derivadas.
C# y C++
En C# , la conversión de tipos se puede realizar de forma segura o insegura (es decir, al estilo de C), la primera se denomina conversión de tipo verificada . [ 9 ]
Animal animal = nuevo Gato ();// si (animal es Bulldog), stat.type(animal) es Bulldog, de lo contrario una excepción Bulldog b = ( Bulldog ) animal ;// si (animal es Bulldog), b = (Bulldog)animal, de lo contrario b = null b = animal como Bulldog ;// elimina la referencia a Cat(), marcándola para la recolección de basura animal = null ;// b == null b = animal como Bulldog ;En C++ se puede lograr un efecto similar utilizando la sintaxis de conversión de tipos al estilo de C++ .
Animal * animal = nuevo Gato ();// compila solo si Animal o Bulldog derivan del otro (o del mismo) Bulldog * b = static_cast < Bulldog *> ( animal );// si (animal es Bulldog), b = (Bulldog*) animal, de lo contrario b = nullptr b = dynamic_cast < Bulldog *> ( animal );// igual que lo anterior, pero se lanzará una excepción si se devuelve un nullptr // esto no se ve en el código donde se evita el manejo de excepciones Bulldog & br = static_cast < Bulldog &> ( * animal );// liberar el animal después de usarlo eliminar animal ; animal = nullptr ;// b == nullptr b = dynamic_cast < Bulldog *> ( animal );Eiffel
En Eiffel, la noción de conversión de tipos está integrada en las reglas del sistema de tipos. La regla de asignación establece que una asignación, como , es válida si y solo si el tipo de su expresión fuente ( ) es compatible con el tipo de su entidad objetivo ( ). En esta regla, compatible con significa que el tipo de la expresión fuente se ajusta o se convierte al del objetivo. La conformidad de tipos se define mediante las reglas de polimorfismo en la programación orientada a objetos . Por ejemplo, en la asignación anterior, el tipo de se ajusta al tipo de si la clase en la que se basa es descendiente de aquella en la que se basa.x := yyxyxyx
Óxido
Rust no proporciona conversión de tipos implícita (coerción) entre la mayoría de los tipos primitivos. Sin embargo, la conversión de tipos explícita (casting) se puede realizar utilizando la aspalabra clave. [ 10 ]
let x : i32 = 1000 ; println! ( "1000 como u16 es: {}" , x as u16 );aserción de tipo
Un concepto relacionado en los sistemas de tipos estáticos es la aserción de tipo , que indica al compilador que trate la expresión de un tipo determinado, sin tener en cuenta su propia inferencia. La aserción de tipo puede ser segura (se realiza una comprobación en tiempo de ejecución) o insegura. Una aserción de tipo no convierte el valor de un tipo de dato a otro.
Mecanografiado
En TypeScript , una aserción de tipo se realiza utilizando la aspalabra clave: [ 11 ]
const myCanvas : HTMLCanvasElement = document.getElementById ( " main_canvas " ) as HTMLCanvasElement ;En el ejemplo anterior, document.getElementByIdse declara que devuelve un HTMLElement, pero sabemos que siempre devuelve un HTMLCanvasElement, que es un subtipo de HTMLElement, en este caso. Si no es así, el código posterior que dependa del comportamiento de HTMLCanvasElementno funcionará correctamente, ya que en TypeScript no hay comprobación en tiempo de ejecución para las aserciones de tipo.
En TypeScript, no hay una forma general de comprobar si un valor es de un tipo determinado en tiempo de ejecución, ya que no hay soporte de tipos en tiempo de ejecución. Sin embargo, es posible escribir una función definida por el usuario que le indique al compilador si un valor es de un tipo determinado o no. Dicha función se llama ` type guard` y se declara con un tipo de retorno ` x is Type,` donde xes un parámetro o this`, en lugar de boolean.
Esto permite que las aserciones de tipo inseguras se contengan en la función de verificación en lugar de estar dispersas por todo el código.
Ir
En Go , se puede usar una aserción de tipo para acceder a un valor de tipo concreto a partir de un valor de interfaz. Es una aserción segura que provocará un pánico (en el caso de un solo valor de retorno) o devolverá un valor cero (si se usan dos valores de retorno) si el valor no es de ese tipo concreto. [ 12 ]
t := i .( T )Estas aserciones de tipo le indican al sistema que ies de tipo T. Si no lo es, entra en pánico.
Conversión implícita mediante uniones sin etiquetar
Muchos lenguajes de programación admiten tipos de unión que pueden contener valores de varios tipos. Algunos lenguajes con comprobación de tipos flexible, como C y PL/I , así como el Pascal original, ofrecen uniones sin etiquetar . Estas se pueden usar para interpretar el patrón de bits de un tipo como un valor de otro tipo.
Problemas de seguridad
En el hacking , la conversión de tipos es el uso indebido de la conversión de tipos para cambiar temporalmente el tipo de datos de una variable respecto a su definición original. [ 13 ] Esto ofrece oportunidades a los hackers, ya que en la conversión de tipos, después de que una variable se convierte a un tipo de datos diferente, el compilador tratará esa variable modificada como el nuevo tipo de datos para esa operación específica. [ 14 ]
Véase también
Referencias
- 1 2 3 Mehrotra, Dheeraj (2008). Ciencias de la Computación de S. Chand . S. Chand. págs. 81–83 . ISBN 978-8121929844.
- ↑ Lenguajes de programación: diseño y estructuras . Laxmi Publications. 2013. pág. 35. ISBN 978-9381159415.
- 1 2 Reilly, Edwin (2004). Enciclopedia concisa de informática . John Wiley & Sons. págs. 82, 110. ISBN 0470090952.
- ↑ Fenton, Steve (2017). Pro TypeScript: Desarrollo de JavaScript a escala de aplicación . Apress. pp. xxiii. ISBN 978-1484232491.
- ↑ "Juego de tipos" . Manual de PHP . Consultado el 27 de enero de 2019 .
- ^ Olsson , Mikaël (2013). Referencia rápida de sintaxis de C++ . Presione. págs. 87 a 89. ISBN 978-1430262770.
- ↑ Kruse, Rudolf; Borgelt, cristiano; Braune, cristiano; Mostaghim, Sanaz; Steinbrecher, Matthias (16 de septiembre de 2016). Inteligencia computacional: una introducción metodológica . Saltador. pag. 269.ISBN 978-1447172963.
- ↑ "Conversiones de tipo no verificadas" . Centro de información de Ada . Consultado el 11 de marzo de 2023 .
- ^ Mössenböck, Hanspeter (25 de marzo de 2002). "C# avanzado: conversiones de tipo marcadas" (PDF) . Institut für Systemsoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. pag. 5 . Consultado el 4 de agosto de 2011 . en el tutorial de C#
- ↑ "Casting" . Rust by Example . Consultado el 1 de abril de 2025 .
- ↑ "Tipos cotidianos" . El manual de TypeScript . Consultado el 1 de abril de 2025 .
- ↑ "Aserciones de tipo" . Un recorrido por Go . Consultado el 1 de abril de 2025 .
- ↑ Erickson, Jon (2008). Hacking: El arte de la explotación . No Starch Press. pág. 51. ISBN 978-1-59327-144-2."La conversión de tipos es simplemente una forma de cambiar temporalmente el tipo de datos de una variable, independientemente de cómo se haya definido originalmente. Cuando una variable se convierte a un tipo diferente, básicamente se le indica al compilador que trate esa variable como si fuera del nuevo tipo de datos, pero solo para esa operación. La sintaxis para la conversión de tipos es la siguiente:
(typecast_data_type) variable..." - ↑ Gopal, Arpita (2009). Magnifying C. PHI Learning Private Limited. pág. 59. ISBN 978-81-203-3861-6."De lo anterior se desprende que el uso de la conversión de tipos consiste en hacer que una variable de un tipo actúe como otro tipo para una única operación. Así, mediante esta capacidad de conversión de tipos, es posible crear caracteres ASCII convirtiendo un entero a su tipo..."
Enlaces externos
- El casting de Ada
- Conversión de tipos en C++
- Guía de referencia de C++: Por qué odio los operadores de conversión de tipos en C++, por Danny Kalev
- Conversión de tipos en Java
- Conversiones implícitas en C#
- Conversión implícita de tipos en Cppreference.com
- Conversiones estáticas y de reinterpretación en C++
- Conversión ascendente y descendente en F#
- Tipos de datos
- Operadores (programación)
- teoría de tipos
- operaciones unarias