rust-tipos-datos-primitivos

Tipos de datos primitivos en Rust: guía práctica esencial

  • 3 min

Los tipos primitivos son los bloques básicos con los que Rust representa valores simples como números, booleanos, caracteres o agrupaciones pequeñas.

Rust es un lenguaje de tipado estático, así que el compilador necesita conocer el tipo de cada valor antes de ejecutar el programa. Muchas veces lo deduce él solito, pero conviene saber qué está deduciendo.

Enteros

Los enteros representan números sin decimales. Rust tiene enteros con signo y sin signo:

TipoRango aproximadoUso típico
i8, i16, i32, i64, i128Con negativosValores que pueden ser menores que cero
u8, u16, u32, u64, u128Cero y positivosTamaños, contadores, bytes
isize, usizeDepende de la arquitecturaÍndices y tamaños de colecciones

Por defecto, Rust usa i32 cuando escribimos un entero sin indicar nada más.

fn main() {
    let edad = 42;        // i32 por defecto
    let puntos: u32 = 100;
    let byte: u8 = 255;
}
Copied!

usize aparece mucho al trabajar con vectores, arrays y strings, porque es el tipo natural para índices y tamaños en memoria.

Números en coma flotante

Para números con decimales tenemos f32 y f64.

fn main() {
    let temperatura = 23.5;      // f64 por defecto
    let sensor: f32 = 0.125;
}
Copied!

Por defecto, Rust usa f64, porque suele ofrecer mejor precisión y en CPUs modernas normalmente no penaliza demasiado.

Los float no son exactos. No uséis f32 o f64 para dinero si necesitáis precisión decimal estricta. Para eso hay tipos específicos o representación en enteros (céntimos, por ejemplo).

Booleanos

El tipo bool solo puede valer true o false.

fn main() {
    let activo = true;
    let terminado: bool = false;
}
Copied!

Se usa en condicionales, flags y cualquier situación donde queramos expresar sí/no, encendido/apagado o verdadero/falso.

Caracteres

El tipo char representa un carácter Unicode, no simplemente un byte.

fn main() {
    let letra = 'a';
    let simbolo = 'ñ';
    let emoji = '🦀';
}
Copied!

En Rust, un char ocupa 4 bytes, porque puede representar cualquier valor Unicode válido.

Tuplas

Una tupla agrupa varios valores de tipos distintos en una sola estructura.

fn main() {
    let persona = ("Luis", 42, true);

    let nombre = persona.0;
    let edad = persona.1;
    let activo = persona.2;
}
Copied!

También podemos desestructurarla:

fn main() {
    let punto = (10, 20);
    let (x, y) = punto;

    println!("x={}, y={}", x, y);
}
Copied!

Las tuplas son útiles para devolver varios valores pequeños sin crear todavía un struct.

Arrays

Un array guarda varios valores del mismo tipo y con longitud fija.

fn main() {
    let numeros = [1, 2, 3, 4, 5];
    let primero = numeros[0];
}
Copied!

También podemos indicar tipo y tamaño:

let sensores: [i32; 4] = [10, 20, 30, 40];
Copied!

Y crear un array repitiendo un valor:

let buffer = [0; 1024]; // 1024 ceros
Copied!

Un array no es un vector. El array tiene tamaño fijo conocido en compilación. El vector (Vec<T>) puede crecer y lo veremos más adelante.

Anotaciones de tipo

Rust infiere tipos muy bien, pero a veces necesitamos ayudarle:

fn main() {
    let numero: u64 = "42".parse().expect("No era un número");
}
Copied!

Sin : u64, el compilador no sabría qué tipo numérico queremos obtener con parse.