Использовать локальные привязки на сайте вызова в макросах Rust "macro_rules"

Рассмотрим следующий фрагмент:

macro_rules! quick_hello {
    ($to_print:expr) => {
        {
            let h = "hello";

            println!("{}", $to_print)
        }
    }
}

fn main() {
    quick_hello!(h);
}

Если я его скомпилирую, то получу:

error[E0425]: cannot find value `h` in this scope
  --> src/main.rs:12:18
   |
12 |     quick_hello!(h);
   |                  ^ not found in this scope

Но не следует ли quick_hello вызывать main развернуть до блока, содержащего let h = "hello" заявление, что позволяет мне использовать его как скороговорку для "привет" на сайте вызова?

Я могу понять, что это сделано для сохранения гигиеничности макросов, но что, если мне потребуется вышеупомянутое поведение? Есть ли способ "выключить" гигиену для этого?

2 ответа

Решение

Как уже отмечалось выше, неясно, что вы хотите от этого макроса. Однако это компилирует и печатает hello:

macro_rules! quick_hello {
    (h) => {
    let h = "hello";
      println!("{}", h)  
    };
    ($to_print:expr) => {
        {
            println!("{}", $to_print)
        }
    }
}
fn main() {
    quick_hello!(h);
}

Обрабатывать quick_hello вызов rustcищет допустимое выражение для $to_print:expr. Но h не является допустимым выражением в этом контексте, поэтому rustc не продвигается вперед с реализацией макроса и выводит ошибку.

Другие вопросы по тегам