Cómo convertir tipos de datos en Go

Introducción

En Go, los tipos de datos se utilizan para clasificar un tipo de dato concreto y determinan los valores que puede asignar al tipo y las operaciones que puede realizar en él. Cuando realice tareas de programación, a veces deberá aplicar conversiones de valores entre tipos para manipular los valores de forma diferente. Por ejemplo, es posible que deba concatenar valores numéricos con cadenas o representar lugares decimales en números que se iniciaron como valores enteros. Los datos generados por el usuario a menudo se asignan al tipo de datos de cadena, incluso si consisten en números; para realizar operaciones matemáticas en esta entrada, tendría que convertir la cadena a un tipo de dato numérico.

Ya que Go es un lenguaje de tipo estático, los tipos de datos se vinculan a variables en lugar de valores. Esto significa que si define una variable como int, solo puede ser int; no puede asignar una string a ella sin convertir el tipo de datos de la variable. En la naturaleza estática de los tipos de datos de Go se da aún más importancia a las formas de convertirlos.

Este tutorial le servirá como guía para convertir números y cadenas, y en él encontrará ejemplos que lo ayudarán a familiarizarse con los diferentes casos de uso.

Convertir tipos de números

Go tiene varios tipos numéricos que puede elegir. Principalmente, se dividen en dos tipos generales: enteros y números de punto flotante.

Existen muchas situaciones en las cuales posiblemente desee aplicar conversiones entre tipos numéricos. Realizar conversiones a diferentes tamaños de tipos numéricos puede servir para optimizar el rendimiento para clases específicas de arquitecturas de sistema. Si dispone de un entero de otra parte de su código y desea hacer una división en él, es posible que desee convertir el entero a un flotante para preservar la precisión de la operación. Además, para trabajar con duraciones de tiempo normalmente es necesario realizar conversiones de enteros. Para abordar estas situaciones, Go tiene conversiones de tipo integradas para la mayoría de los tipos numéricos.

Realizar conversiones a tipos de enteros

Go tiene muchos tipos de datos enteros entre los que se puede elegir. La elección de uno u otro normalmente se relaciona más con el rendimiento; sin embargo, habrá veces en las que necesitará realizar conversiones de un tipo de entero a otro. Por ejemplo, Go a veces genera automáticamente valores numéricos como int, que posiblemente no sea su valor de entrada. Si su valor de entrada fuese int64, no podría usar int y los números int64 en la misma expresión matemática sin antes convertir sus tipos de datos para que coincidan.

Suponga que tiene un inst8 y debe convertirlo en un int32. Puede hacer esto ajustándolo en la conversión de tipo int32():

var index int8 = 15  var bigIndex int32  bigIndex = int32(index)  fmt.Println(bigIndex) 
Output15 

Este bloque de código define index como un tipo de dato int8 y bigIndex como un tipo de dato int32. Para almacenar el valor de index en bigIndex, convierte el tipo de dato en int32. Esto se hace ajustando la conversión de int32() alrededor de la variable index.

Para verificar sus tipos de datos, podría usar la instrucción fmt.Prntf y el verbo %T con la siguiente sintaxis:

fmt.Printf("index data type:    %Tn", index) fmt.Printf("bigIndex data type: %Tn", bigIndex) 
Outputindex data type:    int8 bigIndex data type: int32 

Debido a que esto utiliza el verbo %T, la instrucción de impresión produce el tipo para la variable, no el valor real de esta. De esta forma, puede confirmar el tipo de dato convertido.

También puede realizar conversiones de un entero con un tamaño de bits mayor a un entero con un tamaño de bits menor:

var big int64 = 64  var little int8  little = int8(big)  fmt.Println(little) 
Output64 

Tenga en cuenta que al convertir enteros podría superar potencialmente el valor máximo del tipo de datos y del ajuste:

var big int64 = 129 var little = int8(big) fmt.Println(little) 
Output-127 

Un ajuste tiene lugar cuando el valor se convierte a un tipo de dato que es demasiado pequeño para contenerlo. En el ejemplo anterior, el tipo de dato de 8 bits int8 no tenía suficiente espacio para contener la variable big de 64 bits. Se debe tener cuidado cuando se realicen conversiones de un tipo de dato numérico más grande a un tipo de dato numérico más pequeño, para no truncar los datos por accidente.

Convertir enteros en flotantes

La conversión de enteros en flotantes en Go se asemeja a la conversión de un tipo de entero en otro. Puede usar las conversiones de tipo integradas ajustando float64() o float32() alrededor del entero que convertirá:

var x int64 = 57  var y float64 = float64(x)  fmt.Printf("%.2fn", y) 
Output57.00 

Este código declara una variable x de tipo int64 e inicializa su valor en 57.

var x int64 = 57 

Ajustar la conversión float64() alrededor de x convertirá el valor de 57 en un valor flotante de 57.00.

var y float64 = float64(x) 

El verbo de impresión %.2f indica a fmt.Printf que aplique formato al flotante con dos decimales.

También puede usar este proceso en una variable: Con el siguiente código, se declara f como igual a 57 y luego se imprime el nuevo flotante:

var f float64 = 57 fmt.Printf("%.2fn", f) 
Output57.00 

Usando float32() o float64(), puede convertir enteros en flotantes. A continuación, aprenderá a convertir flotantes en enteros.

Convertir flotantes en enteros

Go puede convertir flotantes en enteros, pero el programa perderá la precisión del flotante.

El ajuste de flotantes en int(), o uno de sus tipos de datos independientes de la arquitectura, funciona de forma similar al que empleó para la conversión de un tipo de entero en otro. Puede añadir un número de punto flotante dentro del paréntesis para convertirlo en un entero.

var f float64 = 390.8 var i int = int(f)  fmt.Printf("f = %.2fn", f) fmt.Printf("i = %dn", i) 
Outputf = 390.80 i = 390 

Esta sintaxis convertiría el flotante 390.8 en el entero 390 y quitaría el lugar decimal.

También puede usar esto con variables. Con el siguiente código se declara que b es igual a 125.0 y que c es igual a 390.8, y luego estos se imprimen como enteros. La declaración de variable corta (:=) acorta la sintaxis:

b := 125.0 c := 390.8  fmt.Println(int(b)) fmt.Println(int(c)) 
Output125 390 

Cuando se convierten flotantes en enteros con el tipo int(), Go corta el decimal y los números restantes de un flotante para crear un entero. Tenga en cuenta que, aunque posiblemente desee redondear 390.8 a 391, Go no hará esto a través del tipo int(). En vez de eso, quitará el decimal.

Números convertidos mediante división

Cuando se dividan tipos de enteros en Go, el resultado será también un tipo de entero, sin el modulus o resto:

a := 5 / 2 fmt.Println(a) 
Output2 

Si, al realizar la división, cualquiera de los tipos numéricos son un flotante, todos los tipos se declararán automáticamente como flotante:

    a := 5.0 / 2     fmt.Println(a) 
Output2.5 

Con esto se divide el flotante 5.0 por el entero 2, y la respuesta 2.5 es un flotante que conserva la precisión decimal.

A lo largo de esta sección, realizó conversiones entre diferentes tipos de datos numéricos, como tamaños de enteros diferentes y números con punto flotante. A continuación, aprenderá a realizar conversiones de números a cadenas.

Realizar conversiones con cadenas

Una cadena es una secuencia de uno o más caracteres (letras, números o símbolos). Las cadenas son una forma de dato común en los programas informáticos y es posible que deba convertir cadenas en números o números en cadenas con bastante frecuencia, sobre todo si toma datos generados por el usuario.

Convertir números en cadenas

Puede convertir números en cadenas usando el método strconv.ltoa del paquete strconv de la biblioteca estándar de Go. Si pasa un número o una variable a los paréntesis del método, ese valor numérico se convertirá en un valor de cadena.

Primero, veremos la forma de convertir enteros. Para convertir el entero 12 a un valor de cadena, puede pasar 12 al método strconv.ltoa:

package main  import (     "fmt"     "strconv" )  func main() {     a := strconv.Itoa(12)     fmt.Printf("%qn", a) } 

Al ejecutar este programa, recibirá el siguiente resultado:

Output"12" 

Las comillas alrededor del número 12 implican que este ya no es un entero, sino que ahora es un valor de cadena.

Utilizó el operador de asignación := para declarar una nueva variable con el nombre a y asignar el valor mostrado de la función strconv.ltoa(). En este caso, asignó el valor 12 a su variable. También usó el verbo %q en la función fmt.Printf, que indica a la función que cite la cadena proporcionada.

Con las variables podrá observar la practicidad de la conversión de enteros en cadenas. Supongamos que desea realizar un seguimiento del progreso de la programación diaria por parte de un usuario e introduce la cantidad de líneas de código que este escribe a la vez. Desearía mostrar esto al usuario e imprimirá los valores de cadenas y enteros al mismo tiempo:

package main  import (     "fmt" )  func main() {     user := "Sammy"     lines := 50      fmt.Println("Congratulations, " + user + "! You just wrote " + lines + " lines of code.") } 

Cuando ejecute este código, verá el siguiente error:

Outputinvalid operation: ("Congratulations, " + user + "! You just wrote ") + lines (mismatched types string and int) 

No puede concatenar cadenas ni enteros en Go. Por lo tanto, deberá convertir la variable lines en un valor de cadena:

package main  import (     "fmt"     "strconv" )  func main() {     user := "Sammy"     lines := 50      fmt.Println("Congratulations, " + user + "! You just wrote " + strconv.Itoa(lines) + " lines of code.") } 

Ahora, cuando ejecute el código verá el siguiente resultado en el que se felicita a su usuario por su progreso:

OutputCongratulations, Sammy! You just wrote 50 lines of code. 

Si desea convertir en una cadena un flotante en vez de un entero, aplicará pasos y un formato similares. Cuando pase un flotante al método fmt.Sprint, desde el paquete fmt de la biblioteca estándar de Go, se mostrará un valor de cadena del flotante. Puede usar el valor flotante o una variable:

package main  import (     "fmt" )  func main() {     fmt.Println(fmt.Sprint(421.034))      f := 5524.53     fmt.Println(fmt.Sprint(f)) } 
Output421.034 5524.53 

Puede realizar una comprobación para asegurarse de que esté bien realizando una concatenación con una cadena:

package main  import (     "fmt" )  func main() {     f := 5524.53     fmt.Println("Sammy has " + fmt.Sprint(f) + " points.") } 
OutputSammy has 5524.53 points. 

Puede estar seguro de que su flotante se convirtió adecuadamente en una cadena porque la concatenación se realizó sin errores.

Convertir cadenas en números

Las cadenas pueden convertirse en números usando el paquete strconv de la biblioteca estándar Go. El paquete strconv tiene funciones para convertir tipos numéricos enteros y flotantes. Ésta es una operación muy común al aceptar entradas del usuario. Por ejemplo, si su programa solicitara la edad de una persona, cuando esta escribiera la respuesta se capturaría como una string. Tendría que convertirla en un int para hacer cualquier operación matemática con ella.

Si su cadena no tiene lugares decimales, probablemente querrá convertirla en un entero usando la función strconv.Atoi. Si sabe que usará el número como un flotante, empleará strconv.ParseFloat.

Usaremos el ejemplo del usuario Sammy realizando un seguimiento de las líneas de código escritas cada día. Es posible que desee manipular esos valores con cálculos matemáticos para proporcionar una respuesta más interesante para el usuario, pero se almacenan actualmente en cadenas:

package main  import (     "fmt" )  func main() {     lines_yesterday := "50"     lines_today := "108"      lines_more := lines_today - lines_yesterday      fmt.Println(lines_more) } 
Outputinvalid operation: lines_today - lines_yesterday (operator - not defined on string) 

Debido a que los dos valores numéricos se hallaban almacenados en cadenas, vio un error. El operando - para la sustracción no es un operando válido para dos valores de cadena.

Modifique el código para incluir el método strconv.Atoi() que convertirá las cadenas en enteros, lo que le permitirá realizar cálculos matemáticos con valores que eran originalmente cadenas. Ya que existe la posibilidad de que se produzcan fallas al convertir una cadena en un entero, debe verificar si hay errores. Puede usar una instrucción if para comprobar si su conversión se realizó correctamente.

package main  import (     "fmt"     "log"     "strconv" )  func main() {     lines_yesterday := "50"     lines_today := "108"      yesterday, err := strconv.Atoi(lines_yesterday)     if err != nil {         log.Fatal(err)     }      today, err := strconv.Atoi(lines_today)     if err != nil {         log.Fatal(err)     }     lines_more := today - yesterday      fmt.Println(lines_more) } 

Debido a que es posible que una cadena no sea un número, el método strconv.Atoi() mostrará el tipo convertido y el posible error. Al realizar una conversión a partir de lines_yesterday con la función strconv.Atoi, debe verificar el valor de retorno err para asegurarse de que el valor se haya convertido. Si err no es nil, significa que strconv.Atoi no pudo convertir correctamente el valor de cadena en un entero. En este ejemplo, usó una instrucción if para verificar si se produjo un error y, si se observó uno, usó log.Fatal para registrarlo y salir del programa.

Cuando ejecute el código anterior, obtendrá lo siguiente:

Output58 

A continuación, intente convertir una cadena que no sea un número:

package main  import (     "fmt"     "strconv" )  func main() {     a := "not a number"     b, err := strconv.Atoi(a)     fmt.Println(b)     fmt.Println(err) } 

Observará el siguiente error:

Output0 strconv.Atoi: parsing "not a number": invalid syntax 

Debido a que se declaró b, pero strconv.Atoi no pudo realizar la conversión, nunca se asignó un valor a b. Observe que b tiene el valor 0. Esto se debe a que Go tiene valores predeterminados, conocidos como valores cero en Go. strconv.Atoi proporciona un error en el que se describe la razón por la que no se pudo convertir también la cadena.

Convertir cadenas y bytes

Las cadenas en Go se almacenan como un segmento de bytes. En Go, puede realizar conversiones de un segmento de bytes a una cadena ajustándola en las conversiones correspondientes de []byte()​​​1​​​ y string().

package main  import (     "fmt" )  func main() {     a := "my string"      b := []byte(a)      c := string(b)      fmt.Println(a)      fmt.Println(b)      fmt.Println(c) } 

Aquí almacenó un valor de cadena en a, luego lo convirtió a un segmento de bytes b y luego convirtió el segmento de bytes de nuevo en una cadena como c. Después, imprimirá a, b y c en la pantalla:

Outputmy string [109 121 32 115 116 114 105 110 103] my string 

La primera línea del resultado es la cadena original my string. La segunda línea impresa es el segmento de bytes que forma la cadena original. En la tercera línea se muestra que el segmento de bytes puede convertirse de forma segura en una cadena e imprimirse de nuevo.

Conclusión

En este tutorial de Go se demostró la forma de convertir varios de los tipos importantes de datos nativos en otros tipos de datos, principalmente mediante métodos integrados. Poder convertir tipos de datos en Go le permitirá hacer cosas como aceptar la entrada de un usuario y realizar cálculos matemáticos en diferentes tipos numéricos. Posteriormente, cuando utilice Go para escribir programas que acepten datos desde muchas fuentes diferentes como bases de datos y API, usará estos métodos de conversión para asegurarse de poder aplicar acciones a sus datos. También podrá optimizar el almacenamiento convirtiendo datos a tipos de datos más pequeños.

Si desea ver un análisis más profundo de los tipos de datos de Go, consulte nuestro artículo Información sobre los tipos de datos de Go.