Melhores Práticas de Macros
Prefira funções, genéricos e traits; use macros quando a sintaxe ou a geração de código exigir. Boas macros têm ótimos erros, testes e gramática de entrada documentada.
Como Usar Esta Lista
- Revise antes de adicionar um novo
macro_rules!ou crate de proc-macro. - Use como checklist para macros de DSL/framework internas.
- Combine com Depurando Macros para o fluxo de trabalho.
A - Quando Usar Macro
- Tente
fn,const fn,trait,implprimeiro. Melhores erros e suporte de IDE. - Use
macro_rules!apenas para sintaxe repetitiva. Não para lógica de negócios. - Use proc macros para derives e atributos. Quando a transformação de AST for necessária.
- Evite macros para ocultar hacks de propriedade. Corrija o design da API em vez disso.
- Documente a gramática de entrada de macro aceita. Exemplos para cada variante.
B - Implementação
- Proc macro em crate separada com
proc-macro = true. Mantenhasynfora do grafo de dependência de tempo de execução. - Use
syn::Error::new_spannedpara diagnósticos. Aponte para o token do usuário, não para os internos da macro. - Suporte genéricos com
split_for_impl. Derives devem funcionar emstruct Foo<T>. - Reemita attrs e visibilidade em itens transformados. Não ignore
#[allow]oupub. - Use caminhos
$crate::emmacro_rules!exportadas. Resolve corretamente a partir da crate consumidora.
C - Teste e Depuração
- Snapshots de
cargo expandpara macros não triviais. Verificados em CI viamacrotestou revisão manual. - Testes de falha de compilação
trybuildpara entrada inválida. Bloqueie mensagens de erro. - Teste unitário de lógica de parse/geração com
proc_macro2. Sem o driver completo do compilador. - Controle
eprintln!de depuração por feature ou env. Sem compilações barulhentas para usuários. - Acompanhe o impacto do tempo de compilação. Divida expansões enormes para
build.rsse necessário.
D - API e Manutenção
- Prefira API pública estável fora da macro. A macro gera um wrapper fino em torno de
fntestadas. - Versionamento de crates de proc-macro com semver. Sintaxe de DSL quebrada é um bump principal.
- Fixe versões de
syn/quoteconscientemente. O alinhamento do workspace reduz a duplicação de syn. - README mostra antes/depois da expansão para um exemplo. Onboarding para consumidores de macro.
- Evite vazar nomes de tipos internos gerados. Superfície pública estável entre releases.
E - Segurança e Correção
- Macros SQL/DSL ainda parametrizam dados do usuário em tempo de execução. String em tempo de compilação não é sanitização.
- Sem sistema de arquivos/rede em proc macros em compilações de CI. Expansão determinística.
- Higiene: evite colidir idents gerados com código do usuário. Use módulos privados ou prefixos únicos.
- Revise
unsafeno código gerado comounsafeescrito à mão. Macro não absolve a revisão. - Audite proc macros de terceiros como qualquer dependência. Risco na cadeia de suprimentos.
FAQs
Quando macro_rules é suficiente?
Literais semelhantes a Vec, pequenos helpers de assert, braços de match repetitivos - não ORMs inteiros.
Aplicativos devem distribuir proc macros?
Geralmente crate de macro publicável separada, mesmo que membro interno de monorepo.
Quantos derives por crate?
Conforme necessário; mantenha derives relacionados juntos; divida se o tempo de compilação prejudicar os consumidores.
negar unsafe no código gerado?
Prefira expansão segura; se unsafe for necessário, documente os invariantes na documentação emitida.
Macro na API pública?
Sim para frameworks; ainda ofereça um caminho de construtor não-macro quando viável para usuários de IDE.
Armadilhas de macro da Edição 2024?
Resolução de caminhos e prelúdios use; teste a expansão sob uma crate consumidora de 2024.
Como ensinar macros para a equipe?
Workshop: expanda o derive do serde, escreva um derive minúsculo, depure com trybuild.
Substituir macro depois?
Planeje um escape hatch: padrão de código gerado estável o suficiente para ser escrito à mão se a macro for removida.
clippy em código gerado?
Lints do Clippy se aplicam à expansão; corrija o gerador, não use allow em todos os lugares.
docs.rs para macros?
Mostre exemplos de expansão na documentação; doc_cfg para caminhos de macro com feature gate.
Relacionado
- Noções Básicas de Macros - introdução
- Depurando Macros - ferramentas
- syn & quote - implementação
- 50 Regras de Rust
Versões de Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.