Macros
- Macros are a way of writing code that writes other code, which is known as metaprogramming.
- Macros can take a variable number of parameters.
- To define a macro, we use the
macro_rules!
construct. - The
#[macro_export]
annotation indicates that this macro should be made available whenever the crate in which the macro is defined is brought into scope. - We must define macros or bring them into scope before you call them in a file, as opposed to functions you can define anywhere and call anywhere.
- References:
macros1.rs
macro_rules! my_macro {
() => {
println!("Check out my macro!");
};
}
fn main() {
// Fix the macro call by adding `!`.
my_macro!();
}
-
This exercise is simple we just need to add
!
when calling the macro.my_macro!();
macros2.rs
// Define macro before using it
macro_rules! my_macro {
() => {
println!("Check out my macro!");
};
}
fn main() {
my_macro!();
}
- This exercise also easy one.
- We just need to move the macro definition before the
main
function.
macros3.rs
// Fix the compiler error without taking the macro definition out of this
// module.
mod macros {
// add export macro attribute
#[macro_export]
macro_rules! my_macro {
() => {
println!("Check out my macro!");
};
}
}
fn main() {
my_macro!();
}
- In this exercise we need to export
my_macro
so it can be accessible inmain
function. - We can do this by adding
#[macro_export]
annotation inmy_macro
definition.
macros4.rs
#[rustfmt::skip]
macro_rules! my_macro {
() => {
println!("Check out my macro!");
}; // add `;`
($val:expr) => {
println!("Look at this other macro: {}", $val);
}; // add `;`
}
fn main() {
my_macro!();
my_macro!(7777);
}
- In this exercise we only need to add
;
for each macro rules statement.