Я начинаю играть с макросами Rust и пришел, чтобы попробовать этот маленький практический пример. Я хочу определить макрос, который расширяется до инициализации переменной (имя не имеет значения) типа i32
(например, но не очень важно) и серии операций с этой переменной, в данном случае var += 1
или var -= 1
и, наконец, он будет вызывать println!("{}", var)
.
Макрос будет принимать серию токенов на основе +
и -
, которые соответствуют операциям, описанным выше.
Так, например:
operate_integer![+++---]
расширится до:
let mut var: i32 = 0;
var += 1;
var += 1;
var += 1;
var -= 1;
var -= 1;
var -= 1;
print!("{}", var);
Я решил использовать для этого 2 макроса, один для упаковки инициализации и печати, а другой для оценки токенов +-
:
Базовым будет:
macro_rules! operate_integer {
// $($all_tokens:tt)* should match everything, it will be forward to the helper macro
($($all_tokens:tt)*) => {
let mut var : i32 = 0;
operate_integer_helper![$($all_tokens:tt)*]
print!("{}", var);
}
}
Помощник расширит операции:
macro_rules! operate_integer_helper {
// the idea is that it matches a `+` followed by more tokens
(+$($t:tt)*) => {
val += 1;
operate_integer_helper![$($t:tt)*] // we recursively handle the remaining tokens
}
(-$($t:tt)*) => {
val -= 1;
operate_integer_helper![$($t:tt)*]
}
}
Это, конечно, не работает, происходит сбой компиляции со следующей ошибкой ( Playground ):
error: no rules expected the token `(`
--> src/lib.rs:102:5
|
102 | (+$($t:tt)*) => {
| ^ no rules expected this token in macro call
Я застрял. Я знаю, что, возможно, мне не хватает многих концепций, так как я только начал, и я был бы очень признателен за помощь в понимании работы с макросами.
Заранее спасибо!