Macros in Rust #1

Macros:

Basically, macros are a way of writing code that writes other code, which is known as metaprogramming. I have also used ‘println!()’ macros in my previous blog. Here macros expand to produce more code than the code you’ve written manually. Metaprogramming helps us to reduce the amount of code we write and maintain.


For Example:

fn main(){
println!("hello");
}

Difference between Macros and Functions:

  • In the function signature, it should declare the number and type of parameter function has.
    Whereas in the case of macros, there we can take a variable number of parameters such as:
  • fn main(){
    let name = "World!";
    println!("hello");
    println!("hello {}", name);
    }
  • The downside to implementing a macro instead of a function is that macro definitions are more complex than function definitions because you’re writing Rust code that writes Rust code.
  • Macro definitions aren’t namespaced within modules like function definitions are. To prevent clashes in the name in external crates, we have to explicitly bring the macros into the scope, at the same time we bring the external crate into scope,  using the annotation. Such as:#[macro_use]
    extern crate serde;
  • We must define macros into scope before we call them in a file. Whereas we can define functions anywhere and call them anywhere.

Types of Macros:

  1. Declarative Macros.
  2. Procedural Macros.

Declarative macro referred to as macros by example, ‘macro_rules!’ macros, or just plain macros. Declarative macros allow you to write something similar to a Rust ‘match’ expression. Such as:

#[macro_export]
macro_rules! vec {
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(
temp_vec.push($x);
)*
temp_vec
}
};
}

Procedural macros are more like functions i.e type of procedure so they are known as Procedural macros. Procedural macros accept some Rust code as an input, operate on that code, and produce some Rust code as an output. Such as:

extern crate hello_macro;
#[macro_use]
extern crate hello_macro_derive;
use hello_macro::HelloMacro;
#[derive(HelloMacro)]
struct Pancakes;
fn main() {
Pancakes::hello_macro();
}

This blog is at glance with types of macros will continue with the briefing in next one.

Reference:
https://doc.rust-lang.org/stable/book/second-edition/

blog-footer

Written by 

Ayush Aggarwal is a Software Consultant having experience of more than 11 months. He has knowledge of various programming languages such as JAVA, C and C++, and also has good knowledge of database technologies like MySQL. He has worked upon Object Oriented Paradigm and a Java and Android enthusiast. His hobbies include playing football, basketball etc.

Leave a Reply

%d bloggers like this: