2017-03-14 44 views
5

我執行拉斯特解析器和空白的是,我想在match模式重用的通用模式。如何在Rust中的變量中存儲模式?

此代碼:

let ch = ' '; 

match ch { 
    ' ' | '\n' | '\t' | '\r' => println!("whitespace"), 
    _ => println!("token"), 
} 

這將得到真正的重複,如果我需要保持對每次指定的空白模式。我想定義一次並重用它。我想要做類似於:

let whitespace = ' ' | '\n' | '\t' | '\r'; 

let ch = ' '; 

match ch { 
    whitespace => println!("whitespace"), 
    _   => println!("token"), 
} 

編譯器不喜歡ws賦值。它解釋|爲二進制操作,而不是交替。

模式可以被存儲在某種程度上變量?有沒有更好或更習慣的方式來做到這一點?

+0

在C這看起來像一個很好的候選人宏,不知道宏在魯斯特也去的方式...... – turbulencetoo

+0

@turbulencetoo一個有趣的想法。在C中,宏是較低級別的文本操作,可能導致無效的源代碼。在Rust中,可以調用宏的地方數量是有限的,擴展必須在語法上有效。我不認爲這些模式是在一組有效的地方。但是,您始終可以使用某種類型的構建腳本來生成恰巧會生成有效Rust代碼的文本文件。 – Shepmaster

回答

10

模式可以被存儲在某種程度上變量?

編號模式是一個編譯時構造,變量包含運行時概念。

有沒有更好或更習慣的方法來做到這一點?

創建一個函數或方法總是避免重複代碼的好方法。

fn is_whitespace(c: char) -> bool { 
    match c { 
     ' ' | '\n' | '\t' | '\r' => true, 
     _ => false, 
    } 
} 

fn main() { 
    let ch = ' '; 

    match ch { 
     x if is_whitespace(x) => println!("whitespace"), 
     _ => println!("token"), 
    } 
} 

我還強烈建議使用現有的解析器,of which there are a multitude,但每個人都希望自己的鏽的「Hello World」進行解析,無論出於何種原因。

我用一個解析庫允許寫代碼類似於此,其中whitespace是知道如何分析有效類型空白的功能:

sequence!(pm, pt, { 
    _   = literal("if"); 
    ws   = whitespace; 
    _   = literal("let"); 
    ws   = append_whitespace(ws); 
    pattern = pattern; 
    ws   = optional_whitespace(ws); 
    _   = literal("="); 
    ws   = optional_whitespace(ws); 
    expression = expression; 
}, |_, _| /* do something with pieces */); 

每個在右側的事情仍然是個別的功能,知道如何解析特定的東西。