codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🦀

Rust

36 / 58 topics
36Macros37Procedural Macros
Tutorials/Rust/Macros
🦀Rust

Macros

Updated 2026-05-15
10 min read

Macros

Introduction

Rust is known for its powerful macro system, which allows you to write code that writes other code. This feature is incredibly useful for reducing boilerplate and enabling metaprogramming. In this section, we'll explore how to create and use macros in Rust.

Macros in Rust are a way to define new syntax that can be expanded into existing Rust code at compile time. They are defined using the macro_rules! macro, which provides a flexible way to match patterns and generate code based on those patterns.

Concept

In Rust, macros are different from functions in several ways:

  1. Compile-time expansion: Macros are expanded at compile time, whereas functions are executed at runtime.
  2. Syntax manipulation: Macros can manipulate the syntax of the code they are applied to, allowing for more flexible and expressive abstractions.
  3. Pattern matching: Macros use pattern matching to determine how to expand the input code.

The macro_rules! macro is the primary way to define macros in Rust. It allows you to specify patterns that match the input code and templates for generating the output code.

Examples

Basic Macro Example

Let's start with a simple example of a macro that prints "Hello, World!" when invoked.

macro_rules! hello_world {
    () => {
        println!("Hello, World!");
    };
}

fn main() {
    hello_world!();
}

In this example:

- `macro_rules!` is used to define the macro named `hello_world`.
- The pattern `()` matches an empty invocation of the macro.
- The template `{ println!("Hello, World!"); }` specifies the code to be generated when the macro is invoked.

When you run this program, it will output:

<OutputBlock>
{`Hello, World!`}
</OutputBlock>

### Macro with Arguments

Macros can also take arguments. Let's create a macro that takes a string and prints it in uppercase.

```rust
macro_rules! print_uppercase {
    ($s:expr) => {
        println!("{}", $s.to_uppercase());
    };
}

fn main() {
    print_uppercase!("hello, world!");
}

In this example:

- The pattern `($s:expr)` matches an expression (in this case, a string literal).
- The template `{ println!("{}", $s.to_uppercase()); }` specifies the code to be generated. It uses the `$s` variable to refer to the matched expression and calls the `to_uppercase()` method on it.

When you run this program, it will output:

<OutputBlock>
{`HELLO, WORLD!`}
</OutputBlock>

### Repetition in Macros

Macros can also handle repetition using the `$( ... )*` or `$( ... )+` syntax. Let's create a macro that takes multiple string arguments and prints each one on a new line.

```rust
macro_rules! print_lines {
    ($($s:expr),*) => {
        $(
            println!("{}", $s);
        )*
    };
}

fn main() {
    print_lines!("Hello", "World", "from", "Rust!");
}

In this example:

- The pattern `$( ... )*` matches zero or more occurrences of the enclosed pattern.
- Each occurrence is separated by a comma.
- The template `$(` ... `)*` specifies that the code inside should be repeated for each matched pattern.

When you run this program, it will output:

<OutputBlock>
{`Hello
World
from
Rust!`}
</OutputBlock>

### Macro with Nested Patterns

Macros can also have nested patterns. Let's create a macro that takes a list of key-value pairs and prints them in a formatted way.

```rust
macro_rules! print_key_value {
    ($($key:expr => $value:expr),*) => {
        $(
            println!("{}: {}", $key, $value);
        )*
    };
}

fn main() {
    print_key_value!(name => "Alice", age => 30, city => "Wonderland");
}

In this example:

  • The pattern $( ... )* matches zero or more occurrences of the enclosed pattern.
  • Each occurrence is separated by a comma.
  • The nested pattern $key:expr => $value:expr matches an expression followed by an arrow and another expression.

When you run this program, it will output:

Output
name: Alice
age: 30
city: Wonderland

What's Next?

In the next section, we'll explore procedural macros, which are a more advanced form of macros that allow for even greater flexibility and power. Procedural macros can generate code based on complex logic and are used in many popular Rust libraries.

Stay tuned for more insights into the macro system in Rust!


PreviousPattern MatchingNext Procedural Macros

Recommended Gear

Pattern MatchingProcedural Macros