- Macros in Rust are a powerful feature that allows you to
define reusable code patterns.
- They are used to generate code at
compile-time
, enablingmetaprogramming
in Rust. - Macros are defined using the
macro_rules!
keyword.
Example:
macro_rules! greet {
() => {
println!("Hello!");
};
}
fn main() {
greet!();
}
Simple Macro
- Macros can take input parameters and generate code based on those parameters.
- The parameters are specified within the macro definition and can be used in the generated code.
- The
($name:ident)
syntax is used to specify an identifier parameter.
Example:
macro_rules! create_function {
($func_name:ident) => {
fn $func_name() {
println!("This is the {} function.", stringify!($func_name));
}
};
}
create_function!(hello);
create_function!(goodbye);
fn main() {
hello();
goodbye();
}
Repetition in Macros
- Macros can repeat code based on a specified pattern.
- The
*
symbol is used to specify repetition in the macro definition. - Repetition can be used to generate multiple lines of code or apply transformations to the repeated code.
Example:
macro_rules! repeat {
($($x:expr),*) => {
$(println!("{}", $x);)*
};
}
fn main() {
repeat!("one", "two", "three");
}
Debugging Macros
- Debugging macros can be challenging since they operate at compile-time.
- To debug macros, you can use the
println!
macro with the#[macro_use]
attribute. - This allows you to print intermediate values during macro expansion.
Example:
#[macro_use]
macro_rules! debug {
($x:expr) => {
println!("{} = {:?}", stringify!($x), $x);
};
}
fn main() {
let x = 42;
debug!(x);
}
Custom Macros
- Rust allows you to define your own custom macros using the
macro
keyword. - Custom macros can provide more flexibility and control over code generation.
- Custom macros can be defined using procedural macros or attribute-like macros.
Example:
#[macro_export]
macro_rules! my_macro {
($x:expr) => {
println!("My custom macro: {}", $x);
};
}
fn main() {
my_macro!("Hello, world!");
}
Top comments (1)
Did you find this post helpful?