Saltar al contenido
En esta página

Macros

Zolo expands macros before type checking and lowering. Use a macro when syntax must be generated or inspected; use a function when ordinary values are enough.

Two declarative forms are available:

  • macro name(args) { ... } is the compact form for expression substitution.
  • macro_rules! name { ... } adds pattern arms, capture kinds, and repetition.

Both forms rename bindings introduced by an expansion so they do not overwrite same-named bindings at the call site.

Compact macro

Parameters are referenced with $name inside the macro body. Invoke the macro with name!(arguments):

macro double(value) {
    $value + $value
}

let result = double!(21)
print(result)

Output:

42

Substitution is syntactic. If an argument appears twice in the body, its expression is evaluated twice after expansion. Bind a value before invoking the macro when duplicate evaluation would be observable.

macro_rules!

macro_rules! tests its arms from top to bottom and expands the first complete match. Captures use $name:kind; supported kinds include expr, ident, ty, lit, pat, block, and tt.

Repetition uses $( ... )* or $( ... )+, with an optional separator before the repetition operator. This example accepts any number of comma-separated expressions:

macro_rules! sum {
    ($($value:expr),*) => {{
        var total = 0
        $( total = total + $value; )*
        total
    }}
}

print(sum!{1, 2, 3, 4})
print(sum!{10, 20})

Output:

10
30

Calls may use braces, brackets, or parentheses. Braces are the clearest choice for macro_rules! because parentheses are also used by the compact macro form.

Hygiene

Bindings created by the expansion receive a unique internal name. Captured identifiers keep the identity of the caller's syntax. You can therefore use a scratch name such as total inside a macro without overwriting a caller's total.

Hygiene is lexical, not a type-system feature. Expansion still happens before the type checker, so invalid generated code is reported only after the macro has expanded.

Dispatch and recursion

Several arms can cover different shapes or arities. If no arm matches the entire token stream, expansion fails with a no matching rule error.

Macros can invoke other macros and can recurse. Expansion depth is capped at 64 so an accidental infinite recursion fails during compilation.

Current limits

  • Procedural @proc_macro declarations are scaffold syntax only. Their bodies are not executed to transform code, so do not use them as a public feature.
  • The declarative matcher is greedy and does not implement Rust's full backtracking behavior for deeply nested repetitions.
  • Diagnostics point at the expanded syntax in some cross-file cases; complete source-context preservation is still pending.

Learn more

Buscar en Zolo

9 resultados

en