rustpattern-matching

Is there a way to name a subexpression of a match pattern?


Is there a way to label a subexpression of a pattern so that the name can be reused? Consider:

fn parse(all_toks : Vec<Token>) -> ParseResult<Form> {
    match all_toks {
        [
            Token::Key(String::from("ALL")),
            Token::Id(a),
            Token::Key(String::from(".")),
            toks @ ..
        ] => {
            let res = parse(toks);
            let mkq = make_quant(
                String::from("ALL"), a);
            apfst(mkq, res)
        }
    }
}

Instead of typing String::from("ALL") again in the let mkq = line, is there a way to both have the match pattern be a literal and also a named variable? Something like (pseudocode):

    match all_toks {
        [
            Token::Key(let x = String::from("ALL")),
            Token::Id(a),
            Token::Key(String::from(".")),
            toks @ ..
        ] => {

or

    match all_toks {
        [
            Token::Key(x),
            Token::Id(a),
            Token::Key(String::from(".")),
            toks @ ..
        ] where (x==String::from("ALL")) => {

Solution

  • In general, yes: that's the @ pattern!

    Token::Key(x @ "ALL")
    

    Even the .. which you used for toks, is a pattern: it's just a pattern that matches everything (a rest pattern).

    However, if, like seen by your code, your types are String and not &str, you have a different problem: patterns can not match Strings (currently), and String::from("...") isn't a valid syntax in pattern. So you cannot use patterns for that.