tipos-datos-basicos-go

Tipos de datos básicos en Go y conversiones explícitas

  • 5 min

Un tipo de dato en Go es la regla que indica qué valores puede guardar una variable y qué operaciones podemos hacer con ella.

Ya sabemos declarar variables, pero… ¿qué podemos guardar en ellas?

Go es un lenguaje de tipado estático y fuerte. Esto significa dos cosas:

  1. Estático: El compilador necesita saber el tipo de cada variable antes de compilar.
  2. Fuerte: El compilador no va a hacer conversiones implícitas por ti. No puedes sumar un número y un texto sin decirle explícitamente cómo hacerlo.

Vamos a ver los tipos básicos predeclarados con los que construiremos todo lo demás.

Números enteros

En Go, los números enteros se dividen en dos familias: con signo (int) y sin signo (uint).

A diferencia de lenguajes como JavaScript (que solo tiene Number para todo), en Go tenemos un control preciso sobre el tamaño en memoria de nuestros números.

Tipos dependientes de la arquitectura

Son los que usaremos el 90% del tiempo.

  • int: tiene 32 o 64 bits según la arquitectura para la que compilemos.
  • uint: tiene el mismo tamaño que int, pero representa números sin signo, incluido el cero.

Aunque en tu máquina int sea de 64 bits, para Go int e int64 son tipos distintos. No puedes asignarlos directamente sin una conversión.

Tipos de tamaño fijo

Si necesitas ahorrar memoria o interactuar con hardware/protocolos binarios, usarás estos:

TipoDescripciónRango aproximado
int88 bits-128 a 127
int1616 bits-32768 a 32767
int3232 bits-2 mil millones a 2 mil millones
int6464 bits−9.22 × 10¹⁸ a 9.22 × 10¹⁸
uint88 bits (unsigned)0 a 255

Alias importantes: byte y rune

En Go verás muy a menudo dos tipos que son en realidad alias de enteros, pero se usan con una intención semántica:

  • byte: Es un alias de uint8. Se usa para representar datos binarios crudos o caracteres ASCII.
  • rune: Es un alias de int32. Se usa para representar un Punto de Código Unicode.
var a int = 10
var b uint8 = 255
var c rune = 'Ñ' // Una rune se define con comillas simples
Copied!

En Go no existe el tipo char. Usamos rune para representar un punto de código Unicode, que puede ocupar más de un byte en UTF-8. Un carácter visual puede estar formado por varias runas, algo frecuente en emojis compuestos.

Números de punto flotante

Para números con decimales, Go simplifica las cosas y nos ofrece dos opciones bajo el estándar IEEE-754:

  • float32: Precisión simple.
  • float64: Doble precisión.
var pi float32 = 3.14
var euler float64 = 2.7182818284
Copied!

¿Cuál usar?

Por defecto, Go infiere float64 cuando escribes un decimal (num := 10.5). Nosotros recomendamos usar siempre float64 a menos que tengas una restricción de memoria muy específica (como en gráficos 3D), ya que float32 acumula errores de redondeo muy rápido.

Booleanos

El tipo bool es el más sencillo. Solo puede valer true o false.

Lo importante aquí es que Go no permite conversiones implícitas.

  • En C o C++, 0 es falso y 1 es verdadero.
  • En Go, 0 es un número y false es un booleano. No se mezclan.
var activo bool = true

// if 1 { ... }  <-- ERROR: "non-bool used as if condition"
// if activo { ... } <-- CORRECTO
Copied!

Cadenas de texto

Internamente, un string en Go es una secuencia inmutable de bytes. Puede contener bytes arbitrarios; por convenio solemos guardar texto UTF-8, y los literales del código fuente se escriben con esa codificación.

Declaración

Podemos usar comillas dobles o comillas invertidas:

// String normal (interpreta caracteres de escape como \n)
saludo := "Hola\nMundo"

// Raw String Literal (ignora escapes, permite multilínea)
html := `
<html>
    <body>Hola</body>
</html>
`
Copied!

Inmutabilidad

En Go, no puedes modificar un string una vez creado.

s := "Gato"
s[0] = 'P' // ERROR: cannot assign to s[0]
Copied!

Si quieres cambiar un string, tienes que crear uno nuevo o convertirlo a un slice de rune o byte, modificarlo y volverlo a convertir.

Repaso de los valores cero

Como mencionamos en el artículo anterior, Go garantiza que toda variable tiene un valor inicial. Esto es importante para la seguridad de memoria. Esta es la tabla de referencia para los tipos básicos:

TipoZero Value
Enteros, float32, float64, byte, rune0
boolfalse
string"" (cadena vacía, NO nula)

Es importante notar que un string vacío tiene longitud 0, pero no es nil.

Conversiones de tipos

Go no convierte implícitamente entre tipos numéricos distintos.

Si quieres sumar un int y un float64, tienes que convertir uno de los dos explícitamente. La sintaxis es Tipo(valor).

package main

import "fmt"

func main() {
    var entero int = 42
    var decimal float64 = 55.5

    // suma := entero + decimal // ERROR: mismatched types int and float64

    // Opción A: Todo a float
    suma := float64(entero) + decimal

    // Opción B: Todo a int (perdiendo decimales)
    sumaEntera := entero + int(decimal)

    fmt.Println(suma)       // 97.5
    fmt.Println(sumaEntera) // 97
}
Copied!

Esto puede parecer verboso al principio, pero hace visible la conversión. No evita por sí solo la pérdida de precisión, el truncado o el desbordamiento: antes de convertir debemos comprobar que el valor cabe en el tipo de destino.