Как мне сопоставить путь или тт в макросе? - PullRequest
0 голосов
/ 12 декабря 2018

Я строю то, что мне показалось довольно простым макросом в Rust для произвольного списка аргументов (str или ansi_term::Style объектов).

Мой макрос выглядит так:

macro_rules! test_macro {
    ( $( $x: tt ),* ) => (
        $(
            print!("{} ", $x);
        )*
        println!();
    )
}

Для минимального рабочего примера я также определил модуль и функцию:

mod foo {
    pub fn test() -> &'static str {
        "doesn't"
    }
}

fn test() -> &'static str {
    "doesn't"
}

Макрос работает с простыми вызовами, такими как

test_macro!("it", "works");

, ноесли я попробую что-нибудь более сложное, я получаю ошибки компилятора:

fn test() -> &'static str {
    "doesn't"
}
test_macro!("it", test(), "work");

приводит к

error: no rules expected the token `(`
   |
24 |     test_macro!("it", test(), "work");
   |                           ^
   |                           |
   |                           help: missing comma here

и

test_macro!("it", foo::test(), "work");

приводит к

error: no rules expected the token `::`
   |
25 |     test_macro!("it", foo::test(), "work");
   |                          ^^

Пример Rust Playground .

Я впервые играю с макросами Rust, поэтому я могу упустить что-то еще.

1 Ответ

0 голосов
/ 14 января 2019

Я думаю, что в вашей логике есть ошибка.Как отметил Маккартон в комментариях , ваш макрос должен быть ( $( $x: expr ),* ), а не ( $( $x: tt ),* ).То есть используйте выражения вместо деревьев токенов.

То, как вы используете макрос для печати, не будет работать с некоторыми возможными значениями, которые присутствуют в деревьях токенов.Я вполне уверен, что вы не можете назвать print!("{}", std::os), что ваш макрос, возможно, позволит.

...