In my previous blog, we have already discussed what macros and why macros. Now in this blog, we will go through the types of macros in detail. So basically we have two types of macros in Rust language i.e Declarative Macros and Procedural Macros.
Declarative Macros:
Actually, we can further divide Declarative macros into two parts ones defined with the macro_rules! keyword, and ones defined with the macro keyword.
macro_rules!:
This is the first line here we have pattern => block. If the pattern match then only code block will be executed.
( $( $x:expr ),* ) => {
The $x:expr part matches an expression, and gives it the name $x. The $(),* part matches zero or more of these expressions. Then, in the body of the macro, the $()* part is generated for each part that matches, and the $x within is replaced with each expression that was matched.
Macro:
As such, the macro keyword was reserved for a new macro system. We’re still not 100% sure if we’re calling these “macros by example”.
Procedural Macros:
In procedural macros, they accept rust code as an input and produce rust code as output.
They’re more like functions (which are a type of procedure) so they are called Procedural Macros.
We’ll create a crate named hello_macro that defines a trait named HelloMacro with one associated function named hello_macro. Rather than making our crate users implement the HelloMacro trait for each of their types, we’ll provide a procedural macro so users can annotate their type with #[derive(HelloMacro)] to get a default implementation of the hello_macro function.
This code will print Hello, Macro! My name is Pancakes! when we are done. The first step is to make a new library crate, like this:
Next, we’ll define the HelloMacro
trait and its associated function:
References:
https://doc.rust-lang.org/stable/book/second-edition/
http://words.steveklabnik.com/an-overview-of-macros-in-rust