Metaprogramação em Rust: macros e poder do código em um novo nível

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que Rust sabe "fazer mágica" com código?

\n\n

Você já escreveu código em Rust e sentiu que estava repetindo as mesmas construções para dezenas de estruturas? Ou gostaria de gerar automaticamente a implementação de uma trait, sem copiar código manualmente? Bem-vindo ao mundo da metaprogramação em Rust — técnicas que permitem escrever código que escreve código.

\n\n

Rust não possui reflexão completa em tempo de execução (como Java ou Python), mas oferece algo mais poderoso e seguro — macros. Elas funcionam em tempo de compilação, analisando e transformando a árvore sintática abstrata (AST). Isso oferece possibilidades incríveis para otimização e redução de código boilerplate sem perda de desempenho.

\n\n

Neste artigo, abordaremos técnicas avançadas de metaprogramação: desde os clássicos macro_rules! até macros procedurais completas. Você aprenderá como criar seus próprios atributos derive e escrever macros de atributo que alteram a semântica do código. Vamos lá!

\n\n

Macros declarativas: macro_rules! — não é apenas "substituição de texto"

\n\n

Muitos pensam que macro_rules! é um pré-processador de texto primitivo. Na verdade, é um poderoso sistema de correspondência de padrões, operando no nível de tokens. Ele permite criar DSLs (linguagens específicas de domínio) diretamente dentro do Rust.

\n\n

Exemplo avançado: criando um builder com macro

\n\n

Imagine que você precisa criar um "construtor" (builder) para uma estrutura. Em vez de escrever dezenas de métodos, você pode escrever uma única macro:

\n\n
macro_rules! builder {\n    ($struct_name:ident, { $($field:ident: $field_type:ty),* $(,)? }) => {\n        struct $struct_name {\n            $($field: Option<$field_type>),*\n        }\n\n        impl $struct_name {\n            $(\n                pub fn $field(mut self, value: $field_type) -> Self {\n                    self.$field = Some(value);\n                    self\n                }\n            )*\n\n            pub fn build(self) -> Result<Self, String> {\n                $(\n                    if self.$field.is_none() {\n                        return Err(format!("Campo {} é obrigatório", stringify!($field)));\n                    }\n                )*\n                Ok(self)\n            }\n        }\n    };\n}\n\nbuilder!(Config, {\n    host: String,\n    port: u16,\n    timeout: u64,\n});\n\nfn main() {\n    let config = Config {\n        host: None,\n        port: None,\n        timeout: None,\n    }\n    .host("localhost".to_string())\n    .port(8080)\n    .build()\n    .unwrap();\n    println!("Config pronto: {}:{}", config.host.unwrap(), config.port.unwrap());\n}\n
\n\n

Esta macro não apenas gera os campos, mas também adiciona validação de campos obrigatórios. Observe o stringify!($field) — ele converte o identificador em uma string em tempo de compilação. Esta é uma técnica típica de metaprogramação avançada em Rust.

\n\n

Repetições e iterações: $(...)* em ação

\n\n

A sintaxe de repetição permite processar listas de argumentos de qualquer comprimento. Combinando ident, ty, expr e outros "fragmentos", você pode criar padrões complexos. Por exemplo, uma macro para criar um enum com implementação automática de Display:

\n\n
macro_rules! display_enum {\n    ($enum_name:ident, { $($variant:ident => $desc:expr),* $(,)? }) => {\n        enum $enum_name {\n            $($variant),*\n        }\n\n        impl std::fmt::Display for $enum_name {\n            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n                match self {\n                    $(Self::$variant => write!(f, "{}", $desc)),*\n                }\n            }\n        }\n    };\n}\n\ndisplay_enum!(Status, {\n    Active => "status_active",\n    Inactive => "status_inactive",\n    Pending => "s                

Blogs

Book Recommendations