25 - Semana cinco completada - construyendo aplicaciones confiables en Rust

25 - Semana cinco completada - construyendo aplicaciones confiables en Rust

Bienvenidos de nuevo a Rustaceo.es. Hemos finalizado la Semana 5 de nuestro recorrido en Rust, en la que nos enfocamos en construir aplicaciones confiables mediante técnicas avanzadas de manejo de errores, pruebas y optimización del código. En este artículo, repasaremos los temas clave que hemos cubierto y cómo aplicarlos en proyectos reales.

Resumen de la semana #

Durante esta semana, exploramos estrategias para garantizar la confiabilidad del código en Rust:

Manejo de errores avanzado: Uso correcto de Result<T, E>, Option<T>, ?, thiserror y anyhow.
Pruebas y aseguramiento de calidad: Implementación de pruebas unitarias, de integración y benchmarks con criterion.
Optimización del código: Identificación de cuellos de botella y mejoras de rendimiento.
Buenas prácticas en desarrollo Rust: Patrones de diseño, seguridad y modularización del código.

Cada uno de estos temas es crucial para construir aplicaciones en Rust que sean seguras y eficientes.


Manejo de errores: construyendo código resistente #

El manejo adecuado de errores es una de las bases para construir aplicaciones confiables. En Rust, evitamos errores silenciosos mediante el uso explícito de Result<T, E> y Option<T>.

Ejemplo: intentando capturar un pokémon #

enum ErrorCaptura {
    SinPokeballs,
    ElementoHuyo,
}

fn intentar_captura(pokeballs: u8) -> Result<&'static str, ErrorCaptura> {
    if pokeballs == 0 {
        return Err(ErrorCaptura::SinPokeballs);
    }
    if rand::random::<f32>() < 0.3 {
        return Err(ErrorCaptura::ElementoHuyo);
    }
    Ok("¡Has capturado al Pokémon!")
}

En este código:

  • Usamos Result<T, E> para manejar fallos en la captura de un Pokémon.
  • Se evita panic!, lo que hace que el programa siga funcionando incluso si la captura falla.

📌 Lección aprendida: Siempre debemos manejar errores explícitamente en Rust para evitar fallos inesperados.


Pruebas en Rust: garantizando código seguro #

Las pruebas en Rust nos ayudan a verificar la funcionalidad del código antes de desplegarlo. Esta semana aprendimos a escribir pruebas unitarias, de integración y benchmarks.

Ejemplo: prueba para verificar el daño de un ataque #

pub fn calcular_dano(ataque: u32, defensa: u32, poder: u32) -> u32 {
    ((ataque as f64 / defensa as f64) * poder as f64 / 50.0 + 2.0) as u32
}

#[Cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_calculo_dano() {
        assert_eq!(calcular_dano(55, 40, 60), 21);
    }
}

📌 Lección aprendida: Rust facilita la escritura de pruebas automatizadas que garantizan la calidad del código y evitan regresiones.


Optimización del código y benchmarks #

Rust nos permite identificar y mejorar el rendimiento del código utilizando herramientas como cargo-flamegraph y criterion.

Ejemplo: benchmark de una función de daño #

use criterion::{criterion_group, criterion_main, Criterion};
use rust_project::calcular_dano;

fn benchmark_calculo_dano(c: &mut Criterion) {
    c.bench_function("calcular_dano", |b| b.iter(|| calcular_dano(55, 40, 60)));
}

criterion_group!(benches, benchmark_calculo_dano);
criterion_main!(benches);

📌 Lección aprendida: Medir el rendimiento nos ayuda a escribir código eficiente y detectar áreas de mejora.


Buenas prácticas en desarrollo con Rust #

Para escribir código confiable, aplicamos las siguientes prácticas:

🔹 Modularización: Separar el código en módulos reutilizables.
🔹 Seguridad en memoria: Evitar referencias nulas y fugas de memoria mediante Rc<T> y RefCell<T>.
🔹 Pruebas continuas: Ejecutar pruebas regularmente para mantener la estabilidad del código.

Estas prácticas garantizan que nuestras aplicaciones sean mantenibles y escalables.


Conclusión #

Esta semana nos ha enseñado cómo escribir código más confiable en Rust mediante:

  • Un manejo de errores estructurado y seguro.
  • Pruebas automatizadas para verificar la funcionalidad.
  • Optimización del rendimiento y benchmarking.
  • Aplicación de buenas prácticas en desarrollo.

Con estas herramientas, estamos listos para construir aplicaciones robustas y eficientes en Rust. En la próxima semana, exploraremos concurrencia y programación asíncrona para mejorar aún más nuestras habilidades.