Tuplas y destructuring en Rust: extraer valores sin repetición

Las tuplas en Rust son la forma más rápida de agrupar varios valores heterogéneos sin definir un struct. Son especialmente útiles para devolver múltiples valores desde una función. El destructuring te permite extraer esos valores en variables individuales con una sintaxis concisa y expresiva.

Tuplas básicas

let punto: (f64, f64) = (3.0, 4.0);
let usuario: (String, u32, bool) = (String::from("Ana"), 42, true);

// Acceso por índice
println!("x={}, y={}", punto.0, punto.1);
println!("Nombre: {}", usuario.0);

Devolver múltiples valores

fn min_max(v: &[i32]) -> (i32, i32) {
    let mut min = v[0];
    let mut max = v[0];
    for &n in v {
        if n < min { min = n; }
        if n > max { max = n; }
    }
    (min, max)
}

fn main() {
    let datos = vec![3, 1, 4, 1, 5, 9, 2, 6];
    let (minimo, maximo) = min_max(&datos);
    println!("min={}, max={}", minimo, maximo);
}

Destructuring en asignaciones

let (a, b, c) = (1, "hola", 3.14);
println!("{} {} {}", a, b, c);

// Ignorar valores con _
let (x, _, z) = (10, 20, 30);
println!("x={}, z={}", x, z);

Destructuring de structs

struct Punto { x: f64, y: f64 }

let p = Punto { x: 1.0, y: 2.0 };
let Punto { x, y } = p;
println!("x={}, y={}", x, y);

// Con renombrado
let p2 = Punto { x: 3.0, y: 4.0 };
let Punto { x: px, y: py } = p2;
println!("px={}, py={}", px, py);

Destructuring en parámetros de función

fn imprimir_punto(&(x, y): &(f64, f64)) {
    println!("({}, {})", x, y);
}

fn main() {
    let p = (3.0, 4.0);
    imprimir_punto(&p);
}

Ignorar campos con ..

struct Config {
    debug: bool,
    nivel: u32,
    nombre: String,
    timeout: u64,
}

let cfg = Config {
    debug: true,
    nivel: 3,
    nombre: String::from("app"),
    timeout: 30,
};

let Config { debug, .. } = cfg; // solo extraemos debug
println!("debug={}", debug);

Error: mover al destructurar

struct Mensaje { contenido: String }

let m = Mensaje { contenido: String::from("hola") };
let Mensaje { contenido } = m; // mueve contenido
// println!("{}", m.contenido); // ERROR: m.contenido se movió

Si quieres evitar el move, usa una referencia:

let ref_msg = &m;
let Mensaje { ref contenido } = *ref_msg;
println!("{}", contenido); // OK, solo presta

O más simplemente, accede al campo directamente sin destructurar si no necesitas moverlo.

Destructuring de enums

enum Forma {
    Circulo(f64),
    Rectangulo(f64, f64),
}

let forma = Forma::Rectangulo(10.0, 5.0);
match forma {
    Forma::Circulo(r)     => println!("Círculo r={}", r),
    Forma::Rectangulo(w, h) => println!("Rect {}x{}", w, h),
}

Resumen

  • Las tuplas agrupan valores heterogéneos sin nombres; acceso por índice (.0, .1…).
  • Sirven para devolver múltiples valores desde una función.
  • El destructuring extrae valores en variables individuales con sintaxis let (a, b) = tupla.
  • Funciona con structs, enums, tuplas y en parámetros de función.
  • Usa _ para ignorar un valor y .. para ignorar el resto.
  • Destructurar puede mover valores; usa referencias si no quieres mover.

El siguiente artículo trata el manejo de errores con Result<T, E>: el sistema que Rust usa en lugar de excepciones para hacer que los errores sean visibles en la firma de cada función.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP