liveBook · Manning

Macro repetition

As explained in Learn Rust in a Month of Lunches

Macro repetition is declarative macro syntax for matching or expanding zero or more or one or more repeated token sequences with optional separators.

In a Rust `macro_rules!` macro, repetition lets one rule accept a variable number of inputs. Put the part to repeat inside `$()`, then choose an operator: `*` means zero or more times, `+` means one or more, and `?` means zero or one. A separator, such as a comma, goes between the closing parenthesis and the operator: `$($input:tt),*`. section 22.2 section 22.3

macro_rules! print_anything {
    ($($input1:tt),*) => {
        let output = stringify!($($input1),*);
        println!("{}", output);
    };
}
 
 
fn main() {
    print_anything!(ththdoetd, rcofe);
    print_anything!();
    print_anything!(87575oehq75onth, ntohe, 987987o, 097);
}

`print_anything!` accepts comma-separated token trees and also accepts an empty call. Its expansion repeats those inputs inside `stringify!`. section 22.2

Choose `+` when an empty call should not match. For example, `$($input:tt),+` requires at least one token tree. The separator is part of the rule: changing its comma to a semicolon means calls must use semicolons too. section 22.2

An optional trailing comma

In `$(,)?`, the repeated part is just a comma. It can appear once or not at all. The `matches!` rule uses it to accept a trailing comma; a separate `$(if $guard:expr)?` makes a match guard optional. section 22.3

macro_rules! make_a_function {
    ($name:ident, $($input:tt),+) => {                        #1
        fn $name() {
            let output = stringify!($($input),+);             #2
            println!("{}", output);
        }
    };
}
 
fn main() {
    make_a_function!(print_it, 5, 5, 6, I);                   #3
    print_it();
    make_a_function!(say_its_nice, this, is, really, nice);   #4
    say_its_nice();
}

`make_a_function!` combines one required function name with one-or-more comma-separated token trees, then repeats the inputs in the generated function. section 22.2

How Learn Rust in a Month of Lunches covers it

How deep it goes
Works through separators and all three repetition operators, including empty input and optional clauses, without descending into compiler internals.
Examples
Shows a printing macro accepting empty and comma-separated calls, a function-generating macro, and optional syntax in `matches!`.
What it assumes
Starts with simple `macro_rules!` examples and introduces token-tree matching before repetition.
What you can do after
Build it from scratch: write macro rules for repeated inputs and optional syntax, then adjust separators to match intended calls.
How it connects
Connects repetition to token trees, `stringify!`, generated functions, trailing commas, match guards, and standard-library macros.

Also explained in

Compare how 2 books explain macro repetition →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.