2015-06-03 2 views
5

В Русте 1.0, нет никакого способа объединения нескольких шаблонов в один переплетеМогут ли макросы расширяться до сочетания шаблонов?

// It does not compile 
match x as char { 
    b @ ('A' | 'Z') => println!("A or Z: {}", b), 
    _ => println!("Try again") 
} 

// Correct version 
match x as char { 
    b @ 'A' | b @ 'Z' => println!("A or Z: {}", b), 
    _ => println!("Try again") 
} 

мне было интересно, если макрос может сделать грязную работу связывания всех различные возможностей. Вот частичная попытка:

macro_rules! bind_alternatives { 
    ($x:ident, $e:expr) => ($x @ $e); 
    ($x:ident, $e1:expr, $e2:expr) => (
     $x @ $e1 | $x @ $e2 
    ); 
} 

fn main() { 
    let x = 'a'; 

    match x { 
     bind_alternatives!(z, 'a', 'c') => println!("Matched"), 
     _ => println!("No luck") 
    }; 
} 

Это не компилируется:

example.rs:4:18: 4:19 error: macro expansion ignores token `|` and any following 
example.rs:4   $x @ $e1 | $x @ $e2 
            ^
example.rs:12:9: 12:40 note: caused by the macro expansion here; the usage of `bind_alternatives` is likely invalid in this context 
example.rs:12   bind_alternatives!(z, 'a', 'c') => println!("Matched"), 

Я понимаю, что макросы могут быть расширены в модели, и первая фигурная скобка bind_alternatives делает работу. Можно ли обобщить более чем на 1 возможность? Если нет, что мешает?

+1

У меня нет полного ответа, но '' a '| 'c'' не является шаблоном, это синтаксис для соответствия шаблону. – bluss

ответ

4

Макрос может расширяться до таких вещей, как шаблоны, выражения и элементы, но не все; в частности, макросы расширяются до завершения узлов AST, но то, с чем вы имеете дело, не является полным узлом AST.

Каждая ветвь выражения match может иметь один или несколько узоров, разделенных трубами, и дополнительный защитный узор (if condition). Все это особый синтаксис match, и, следовательно, не полный узел AST, и, следовательно, не то, к чему может расширить макрос.

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

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