What are macros in Rust?

Macros are used in Rust to generate code on compile time, which is also known as metaprogramming. These are used to reduce the frequency of repetitive tasks and the need for boilerplate code. In Rust, we typically encounter two types of macros:

  1. Declarative macros: These are the syntactic macros in Rust. This is mostly based on pattern matching and substitution.

  2. Procedural macros: These have more flexibility and power when compared with declarative macros. These are usually based on runtime analysis and code generation.

Here, we will take a look at how these macros are used through a coding example.

Example

Let's take a look at macros with a coding example:

macro_rules! sqrt {
($x:expr) => {
($x as f64).sqrt()
};
}
fn main() {
let x: f64 = 64.0;
let result = sqrt!(x);
println!("The square root of {} is {}", x, result);
}

Explanation

This code is explained below:

  • Line 1: Defining the sqrt macro. We use the macro_rules! syntax, so this is a declarative macro.

  • Line 2: We define the pattern the macro matches when invoked. In this case, the expression represents the input that will be passed to the macro.

  • Line 3: When the macro is invoked with an expression, it will be replaced with the code on this line (having sqrt called on it). This is the expansion of the macro.

  • Line 7: Start of the main function.

  • Line 8: Declare a variable x of type f64 (64-bit floating-point). It has the value 64.

  • Line 9: This invokes the sqrt macro onto x.

  • Line 10: Print the results.

In the code above, we can test other values by changing x to whatever we wish on line 8. In the case of procedural macros, the macro definition needs to be compiled and used within a separate Rust project as a dependency.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved