macro_rules!

Rust proporciona un potente sistema de macros que permite la metaprogramación. Como has visto en capítulos anteriores, los macros parecen funciones, excepto que su nombre termina con un signo de exclamación !, pero en lugar de generar una llamada de función, los macros se expanden en el código fuente que se compila con el resto del programa. Sin embargo, a diferencia de las macros en C y otros lenguajes, los macros de Rust se expanden en árboles de sintaxis abstractos, en lugar de preprocesamiento de cadenas, por lo que no obtienes errores de precedencia inesperados.

Los macros se crean usando el macro macro_rules!.

// Este es una macro simple llamado `di_hola`.
macro_rules! di_hola {
    // `()` indica que el macro no acepta argumentos.
    () => {
        // El macro se expandirá al contenido de este bloque.
        println!("¡Hola!");
    };
}

fn main() {
    // Esta llamada se expandirá a `println!("¡Hola!");`
    di_hola!()
}

Entonces, ¿por qué son útiles los macros?

  1. No te repitas. Hay muchos casos en los que es posible que necesites una funcionalidad similar en varios lugares pero con diferentes tipos. A menudo, escribir un macro es una forma útil de evitar la repetición de código. (Más sobre esto más adelante)

  2. Lenguajes específicos de dominio. Los macros te permiten definir una sintaxis especial para un propósito específico. (Más sobre esto más adelante)

  3. Interfaces variadicas. A veces, deseas definir una interfaz que tenga un número variable de argumentos. Un ejemplo es println! que puede tomar cualquier número de argumentos, dependiendo de la cadena de formato!. (Más sobre esto más adelante)