2016-09-18 2 views
0

Возможно ли написать макрос, который расширяет выражение на несколько индексированных аргументов, которые могут быть переданы функции или другому макросу?Могут ли макросы развернуть массив/вектор в несколько индексированных аргументов?

См. Этот простой самостоятельный пример.
Цель состоит в том, чтобы иметь unpack3 развернуть v в v[0], v[1], v[2].

macro_rules! elem { 
    ($val:expr, $($var:expr), *) => { 
     $($val == $var) || * 
    } 
} 

// attempt to expand an array. 
macro_rules! unpack3 { 
    ($v:expr) => { 
     $v[0], $v[1], $v[2] 
    } 
} 

fn main() { 
    let a = 2; 
    let vars = [0, 1, 3]; 
    // works! 
    if elem!(a, vars[0], vars[1], vars[2]) { 
     println!("Found!"); 
    } 
    // fails! 
    if elem!(a, unpack3!(vars)) { 
     println!("Found!"); 
    } 
} 

Второй пример не удается, возможно ли сделать эту работу?

Возможные решения могут включать в себя:

  • Изменение использования макросов грамматики.
  • Использование кортежей, а затем расширение в аргументы после.
  • Повторное размещение выражений для обходных ограничений макросов.

Заметим, что это может быть связано с Escaping commas in macro output, но не думаю, что его дубликат.

ответ

7

Это невозможно по-разному.

Во-первых, процитировать ответ на этот вопрос вы сами связаны между собой:. «Нет, результат макро должен быть полная грамматика строится как выражение или деталь Вы абсолютно не имеют случайные биты синтаксиса как запятая или закрывающая скобка ». Просто потому, что это не точно запятая не меняет вопросы: набор аргументов функции не полная грамматическая конструкция.

Во-вторых, макросы не могут анализировать выходные данные других макросов. Это требует энергичного расширения, которого Rust не имеет. You can only do this using recursion.

Смежные вопросы