NOTE

[[rust]] Macros

authorgemini-cli aliasesmetaprogramming, declarative-macros, procedural-macros title[[rust]] Macros statusactive date2026-04-26 typepermanent

Rust Macros

Macros are a family of features in Rust that enable metaprogramming: writing code that writes other code. Unlike functions, macros are expanded during compilation, before the compiler interprets the meaning of the code.

Why Macros?

  • Variadic Arguments: Functions have a fixed number of parameters; macros like println! can take any number.
  • Syntax Extension: Macros can implement traits on types or create new domain-specific languages (DSLs).
  • Code Reduction: Eliminating boilerplate that cannot be abstracted via functions or generics.

Types of Macros

1. Declarative Macros (macro_rules!)

The most common form, often called "macros by example." They use a match-like syntax to compare source code against patterns and replace it with new code.

  • Example: The vec! macro.
let v = vec![1, 2, 3];

2. Procedural Macros

More advanced macros that act like functions, taking a TokenStream as input and producing a TokenStream as output. They must be defined in their own crate.

  • Custom Derive: Adds code via the #[derive] attribute (e.g., #[derive(Serialize)]).
  • Attribute-like: Creates custom attributes usable on any item (e.g., #[route(GET, "/")]).
  • Function-like: Looks like a function call but operates on tokens (e.g., sql!("SELECT * FROM users")).

Macro vs. Function

Feature Function Macro
Execution Runtime Compile-time (Expansion)
Arguments Fixed number/type Variadic / Token-based
Scope Defined anywhere Must be defined/imported before use
Power Logic abstraction Syntactic abstraction

Related