CodeBlanks Logo Icon CodeBlanks

macro_rules!

Define macros with macro_rules!.

macro_rules!

Declarative macros are pattern matchers that generate code. Their differences from functions: they expand at compile time, can take a variable number of arguments and work with code fragments like expressions, types or items:

macro_rules! kare {
    ($x:expr) => {
        ($x) * ($x)
    };
}

let a = kare!(4);       // (4) * (4)
let b = kare!(1 + 2);   // (1 + 2) * (1 + 2) = 9

$x:expr is a fragment: "an expression named x". The parentheses in the body matter; without them kare!(1 + 2) would be 1 + 2 * 1 + 2 = 5.

Macro or function?

If a function does the job, write a function: type checking, documentation and error messages are better. A macro is needed when: there's a variable number of arguments (println!, vec!), repetitive code must be generated (the same impl for many types), or you must work on a code fragment at compile time (stringify!, the message of assert_eq!).

// cargo expand: shows the macro's expanded form
// $ cargo install cargo-expand && cargo expand

Practice First macro

Write the kare! macro above with the parenthesized body. Print the results of kare!(4) and kare!(1 + 2) separated by a space.

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
macro_rules! kare {
    ($x:expr) => {
        ($x) * ($x)
    };
}

fn main() {
    println!("{} {}", kare!(4), kare!(1 + 2));
}

Expected output

16 9

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why must a macro be defined before it's called?

  • It isn't needed
  • Because the compiler is slow
  • Only in tests
  • macro_rules! macros become visible in source order Correct answer

Explanation: Using them from other modules needs #[macro_export] or module ordering; functions have no such restriction.

2 Expression fragment

Question
macro_rules! kare {
    ($x:____) => {
        ($x) * ($x)
    };
}
Answer
macro_rules! kare {
    ($x:expr) => {
        ($x) * ($x)
    };
}

Explanation: The expr fragment matches a Rust expression.

3 Call and result

Term Meaning
kare!(4) 16
kare!(1 + 2) 9
kare!(-3) 9 (negative)
Parantezsiz $x * $x ile kare!(1 + 2) 5

All lessons in Advanced