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:
- Estático: El compilador necesita saber el tipo de cada variable antes de compilar.
- 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 queint, 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:
| Tipo | Descripción | Rango aproximado |
|---|---|---|
int8 | 8 bits | -128 a 127 |
int16 | 16 bits | -32768 a 32767 |
int32 | 32 bits | -2 mil millones a 2 mil millones |
int64 | 64 bits | −9.22 × 10¹⁸ a 9.22 × 10¹⁸ |
uint8 | 8 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 deuint8. Se usa para representar datos binarios crudos o caracteres ASCII.rune: Es un alias deint32. 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 simplesEn 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¿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++,
0es falso y1es verdadero. - En Go,
0es un número yfalsees un booleano. No se mezclan.
var activo bool = true
// if 1 { ... } <-- ERROR: "non-bool used as if condition"
// if activo { ... } <-- CORRECTOCadenas 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>
`Inmutabilidad
En Go, no puedes modificar un string una vez creado.
s := "Gato"
s[0] = 'P' // ERROR: cannot assign to s[0]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:
| Tipo | Zero Value |
|---|---|
Enteros, float32, float64, byte, rune | 0 |
bool | false |
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
}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.