首页 文章

如何在Rust中的变量中存储模式?

提问于
浏览
6

我正在Rust中实现一个解析器,而空白是我想在 match 模式中重用的常见模式 .

此代码有效:

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 赋值 . 它将 | 解释为二进制运算而不是交替运算 .

模式可以以某种方式存储在变量中吗?是否有更好或更惯用的方法来做到这一点?

1 回答

  • 11

    模式可以以某种方式存储在变量中吗?

    编号模式是编译时构造,变量包含运行时概念 .

    有没有更好或更惯用的方法来做到这一点?

    创建函数或方法始终是避免重复代码的好方法 .

    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,但是无论出于什么原因,每个人都希望他们的Rust "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 */);
    

    右侧的每个东西仍然是知道如何解析特定内容的单个函数 .

相关问题