> For the complete documentation index, see [llms.txt](https://bagus-cahyono.gitbook.io/programming-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bagus-cahyono.gitbook.io/programming-notes/rust/rustlings_exercise/21_macros.md).

# Macros

* Macros are a way of writing code that writes other code, which is known as ***metaprogramming***.
* Macros can take a variable number of parameters.
* To define a macro, we use the `macro_rules!` construct.
* The `#[macro_export]` annotation indicates that this macro should be made available whenever the crate in which the macro is defined is brought into scope.
* We must define macros or bring them into scope before you call them in a file, as opposed to functions you can define anywhere and call anywhere.
* References:
  * [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html)

## macros1.rs

```rust
macro_rules! my_macro {
    () => {
        println!("Check out my macro!");
    };
}

fn main() {
    // Fix the macro call by adding `!`.
    my_macro!();
}
```

* This exercise is simple we just need to add `!` when calling the macro.

  ```rust
  my_macro!();
  ```

## macros2.rs

```rust
// Define macro before using it
macro_rules! my_macro {
    () => {
        println!("Check out my macro!");
    };
}

fn main() {
    my_macro!();
}
```

* This exercise also easy one.
* We just need to move the macro definition before the `main` function.

## macros3.rs

```rust
// Fix the compiler error without taking the macro definition out of this
// module.
mod macros {
    // add export macro attribute
    #[macro_export]
    macro_rules! my_macro {
        () => {
            println!("Check out my macro!");
        };
    }
}

fn main() {
    my_macro!();
}
```

* In this exercise we need to export `my_macro` so it can be accessible in `main` function.
* We can do this by adding `#[macro_export]` annotation in `my_macro` definition.

## macros4.rs

```rust
#[rustfmt::skip]
macro_rules! my_macro {
    () => {
        println!("Check out my macro!");
    }; // add `;`
    ($val:expr) => {
        println!("Look at this other macro: {}", $val);
    }; // add `;`
}

fn main() {
    my_macro!();
    my_macro!(7777);
}
```

* In this exercise we only need to add `;` for each macro rules statement.
