Factorizando la Repetición con Macros de Rust

RustRustBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, exploramos el concepto de DRY (Don't Repeat Yourself) en la codificación mediante el uso de macros para extraer las partes comunes de funciones y suites de pruebas.

Nota: Si el laboratorio no especifica un nombre de archivo, puede usar cualquier nombre de archivo que desee. Por ejemplo, puede usar main.rs, compilar y ejecutarlo con rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/ControlStructuresGroup(["Control Structures"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/BasicConceptsGroup -.-> rust/mutable_variables("Mutable Variables") rust/ControlStructuresGroup -.-> rust/for_loop("for Loop") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99228{{"Factorizando la Repetición con Macros de Rust"}} rust/mutable_variables -.-> lab-99228{{"Factorizando la Repetición con Macros de Rust"}} rust/for_loop -.-> lab-99228{{"Factorizando la Repetición con Macros de Rust"}} rust/expressions_statements -.-> lab-99228{{"Factorizando la Repetición con Macros de Rust"}} rust/method_syntax -.-> lab-99228{{"Factorizando la Repetición con Macros de Rust"}} rust/operator_overloading -.-> lab-99228{{"Factorizando la Repetición con Macros de Rust"}} end

DRY (Don't Repeat Yourself)

Las macros permiten escribir código DRY extrayendo las partes comunes de funciones y/o suites de pruebas. Aquí hay un ejemplo que implementa y prueba los operadores +=, *= y -= en Vec<T>:

use std::ops::{Add, Mul, Sub};

macro_rules! assert_equal_len {
    // El designador `tt` (árbol de tokens) se utiliza para
    // operadores y tokens.
    ($a:expr, $b:expr, $func:ident, $op:tt) => {
        assert!($a.len() == $b.len(),
                "{:?}: error de dimensión: {:?} {:?} {:?}",
                stringify!($func),
                ($a.len(),),
                stringify!($op),
                ($b.len(),));
    };
}

macro_rules! op {
    ($func:ident, $bound:ident, $op:tt, $method:ident) => {
        fn $func<T: $bound<T, Output=T> + Copy>(xs: &mut Vec<T>, ys: &Vec<T>) {
            assert_equal_len!(xs, ys, $func, $op);

            for (x, y) in xs.iter_mut().zip(ys.iter()) {
                *x = $bound::$method(*x, *y);
                // *x = x.$method(*y);
            }
        }
    };
}

// Implementa las funciones `add_assign`, `mul_assign` y `sub_assign`.
op!(add_assign, Add, +=, add);
op!(mul_assign, Mul, *=, mul);
op!(sub_assign, Sub, -=, sub);

mod test {
    use std::iter;
    macro_rules! test {
        ($func:ident, $x:expr, $y:expr, $z:expr) => {
            #[test]
            fn $func() {
                for size in 0usize..10 {
                    let mut x: Vec<_> = iter::repeat($x).take(size).collect();
                    let y: Vec<_> = iter::repeat($y).take(size).collect();
                    let z: Vec<_> = iter::repeat($z).take(size).collect();

                    super::$func(&mut x, &y);

                    assert_eq!(x, z);
                }
            }
        };
    }

    // Prueba `add_assign`, `mul_assign` y `sub_assign`.
    test!(add_assign, 1u32, 2u32, 3u32);
    test!(mul_assign, 2u32, 3u32, 6u32);
    test!(sub_assign, 3u32, 2u32, 1u32);
}
$ rustc --test dry.rs && ./dry
ejecutando 3 pruebas
test test::mul_assign... ok
test test::add_assign... ok
test test::sub_assign... ok

resultado de las pruebas: ok. 3 pasadas
0 fallidas
0 ignoradas
0 medidas

Resumen

¡Felicidades! Has completado el laboratorio de DRY (Don't Repeat Yourself). Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.