30 days of Rust - Day Twenty Three - Macros
Did you know that println!
used to print a line in the console is not a function? I was quite amazed when I heard this. It is actually a macro
instead. Let's have a quick look at them.
Day 23 - Macros
Macros are Rust's way of reducing the amount of code we'd have to write and maintain. Macros are basically code which generates other code, which is called metaprogramming
. Side note, it has nothing to do with the metaverse 🤣 .
This is a rather advanced concept in Rust and I found it very difficult to even read the syntax used by macro definitions.
Note that unlike functions, macros are only available before the code is compiled. At compile time, the macros are changed into code.
So let's look at a high level example of the vec!
macro, which allows us to create a new vector.
let v: Vec<&str> = vec!["Masai", "Njabulo", "Musa"];
A high level view of the implementation of the macro is as follows;
#[macro_export]
macro_rules! vec {
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(
temp_vec.push($x);
)*
temp_vec
}
};
}
The #[macro_export]
annotation indicates that the macro should be public and available when the crate is in brought into scope. By default it's private and won't be available.
macro_rules!
is used to define the macro, followed by the name of the macro, which in this case is vec
.
Provided that the inputs to our macro match the expression below, the code inside the code block following the =>
will be generated.
The code below says match any expression and assign it to $x
.
( $( $x:expr ),* )
So calling the macro as follows vec!["Masai", "Njabulo", "Musa"]
will match for each name inside, assign it to $x
and then push each name inside a Vector.
the output code will then be;
{
let mut temp_vec = Vec::new();
temp_vec.push("Masai");
temp_vec.push("Njabulo");
temp_vec.push("Musa");
temp_vec
}
Conclusion
Honestly, I think this concept still flies over my head. I get the idea why it's useful, but I think one should consider the added level of complexity when creating their own macros. I guess as time goes on it should come natural, but as for now I shall stick to code that's not DRY (Don't repeat yourself).🤣
Thanks for spending some time learning Rust with me. Until next time. Peace ✌🏼 .