macro_rules!
- Rust course
- Advanced
- Lesson 42/81
- 4 min
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 expandPractice 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
fn main() {
// buraya yaz
}Sample solution
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
macro_rules! kare {
($x:____) => {
($x) * ($x)
};
}
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 |