Programación funcional en Rust: enfoques y ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción a la programación funcional en Rust

Rust es un lenguaje multiparadigma que, junto con los estilos imperativo y orientado a objetos, admite activamente la programación funcional. Herramientas integradas como closures, iteradores, un potente sistema de tipos e inmutabilidad por defecto permiten escribir código conciso, seguro y expresivo. En este artículo, analizaremos los conceptos clave del enfoque funcional en Rust y mostraremos cómo aplicarlos en la práctica.



Fundamentos del enfoque funcional: inmutabilidad y funciones puras

La programación funcional se basa en dos pilares: inmutabilidad de datos y funciones puras. Rust fomenta la inmutabilidad: por defecto, todas las variables son inmutables. Para cambiar un valor, debes indicar explícitamente mut.

fn main() {    let x = 5; // variable inmutable    // x = 6; // error de compilación    let mut y = 10;    y += 5; // permitido, ya que y es mutable    println!("x = {}, y = {}", x, y);}

Una función pura no tiene efectos secundarios y siempre devuelve el mismo resultado para los mismos argumentos. Rust permite escribir tales funciones, pero no obliga a ello: puedes mezclar estilos libremente.

fn add(a: i32, b: i32) -> i32 {    a + b // función pura}


Closures — funciones anónimas

Los closures en Rust son funciones anónimas que pueden capturar variables del ámbito circundante. Se definen con la sintaxis |parámetros| cuerpo. Los closures son de tres tipos según la forma de captura: por referencia (&T), por referencia mutable (&mut T) y por valor (T).

Ejemplo simple de closure

fn main() {    let factor = 2;    let multiply = |x: i32| x * factor;    println!("{}", multiply(10)); // 20}

Closure con captura mutable

fn main() {    let mut counter = 0;    let mut increment = || {        counter += 1;        counter    };    println!("{}", increment()); // 1    println!("{}", increment()); // 2}

Los closures se usan ampliamente con iteradores y para pasar comportamiento a funciones de orden superior.



Iteradores y cadenas funcionales

Los iteradores en Rust son una de las abstracciones funcionales más potentes. En lugar de bucles, puedes construir cadenas de métodos como map, filter, fold y otros. Los iteradores son perezosos: los cálculos solo ocurren al llamar a un consumidor (por ejemplo, collect o for_each).

Ejemplo: filtrado y transformación

fn main() {    let numbers = vec![1, 2, 3, 4, 5, 6];    let result: Vec<i32> = numbers        .iter()        .filter(|&x| x % 2 == 0) // dejamos los pares        .map(|x| x * x)          // elevamos al cuadrado        .collect();    println!("{:?}", result); // [4, 16, 36]}

Fold — acumulación de valores

fn main() {    let numbers = vec![1, 2, 3, 4];    let sum = numbers.iter().fold(0, |acc, x| acc + x);    println!("Suma: {}", sum); // 10}

Los iteradores hacen que el código sea declarativo: describes qué se debe hacer, no cómo. Esto reduce la probabilidad de errores y mejora la legibilidad.



Pattern matching

La construcción match es un elemento central del estilo funcional en Rust. Permite desestructurar estructuras de datos complejas, manejar variantes de Option y Result, y escribir comprobaciones exhaustivas.

Ejemplo básico

fn describe_number(n: i32) -> &'static str {    match n {        0 => "cero",        1 | 2 => "número pequeño",        3..=10 => "número mediano",        _ if n < 0 => "negativo",\                

Blogs

Book Recommendations