Definição e Invocação
Nesta página
Um macro é declarado com a palavra-chave macro, seguida do nome, dos
parâmetros entre parênteses e do corpo entre chaves. No corpo, cada parâmetro
é referenciado com o prefixo $. A invocação usa name!(arg) — o ! final
é a convenção visual que distingue macros de chamadas de função.
O argumento pode ser qualquer expressão: literal, aritmética, chamada de
função. A substituição é textual, então double!(5 + 5) expande para
(5 + 5) + (5 + 5):
Macro de um parâmetro: double! demonstra substituição textual com literais, aritmética e chamada de função.
// Feature: Macros — basic definition
// Syntax: `macro name(p1, p2) { ... }` + invocation `name!(arg)`
// When to use: generate repetitive code at expansion time (before
// typecheck and lowering). Useful to wrap textual patterns that a
// function cannot capture — `stringify!`, `assert!`, `dbg!`, etc.
// Simplest macro: doubles the received expression.
// Note: parameters are referenced with `$name` in the body.
macro double(x) {
$x + $x
}
// Invocation uses `!` at the end — convention that distinguishes from a regular function.
let result = double!(21)
print(result)
// expected: 42
// The argument can be any expression — it is pasted textually.
print(double!(5 + 5))
// expected: 20
// Macros are purely syntactic: you can pass identifiers, function
// calls, literals, arithmetic expressions...
fn ten() -> int {
return 10
}
print(double!(ten()))
// expected: 20
Quando mais de um valor precisa ser combinado, declare vários parâmetros.
show_pair! ilustra interpolação de string com dois parâmetros; pick! usa
três para implementar um condicional embutido:
sum3!, show_pair! e pick! mostram múltiplos parâmetros e expansão condicional.
// Feature: Macros with multiple parameters
// Syntax: `macro name(a, b, c) { ... }` — any fixed number of params
// When to use: combine or compare multiple expressions at one expansion
// site.
// Sum of three expressions.
macro sum3(a, b, c) {
$a + $b + $c
}
print(sum3!(1, 2, 3))
// expected: 6
// Print two arguments with a label.
macro show_pair(label, value) {
print("{$label} = {$value}")
}
show_pair!("count", 42)
show_pair!("name", "zolo")
// expected:
// count = 42
// name = zolo
// Ternary comparison via macro.
macro pick(cond, a, b) {
if $cond { $a } else { $b }
}
let x = 7
let max = pick!(x > 5, x, 5)
print(max)
// expected: 7
Desafio
Crie um macro clamp!(val, lo, hi) que retorna lo se val < lo, hi se
val > hi, ou val caso contrário. Teste com clamp!(15, 0, 10) e
clamp!(-5, 0, 10).
Veja também