Rust中如何为match模式的子表达式命名以实现复用?
可行实现方案
针对你想在match模式中既匹配目标字面量又绑定变量复用的需求,有几种简洁的实现方式:
1. 模式绑定(@符号)
这是最直接的方案,利用Rust的@操作符,在匹配目标值的同时将其绑定到变量:
fn parse(all_toks : Vec<Token>) -> ParseResult<Form> { match all_toks { [ Token::Key(x @ String::from("ALL")), Token::Id(a), Token::Key(String::from(".")), toks @ .. ] => { let res = parse(toks); let mkq = make_quant(x, a); // 直接复用绑定的x变量 apfst(mkq, res) } } }
x @ String::from("ALL")的含义是:匹配Token::Key包裹的String::from("ALL")值,并将这个值绑定到变量x,后续代码直接使用x即可,无需重复构造字符串。
2. 匹配守卫(优化你的示例2)
你的示例2思路可行,只需调整写法确保类型匹配,利用匹配守卫的if条件判断变量值,同时绑定变量:
fn parse(all_toks : Vec<Token>) -> ParseResult<Form> { match all_toks { [ Token::Key(x), Token::Id(a), Token::Key(String::from(".")), toks @ .. ] if x == String::from("ALL") => { let res = parse(toks); let mkq = make_quant(x, a); // 复用绑定的x apfst(mkq, res) } } }
这种方式适合匹配条件更复杂的场景,但对于简单的相等判断,@绑定的写法更简洁直接。
3. 结合常量提升可维护性
如果"ALL"和"."这类字符串会在多处使用,建议先定义常量,进一步减少重复代码并提升维护性:
const ALL: &str = "ALL"; const DOT: &str = "."; fn parse(all_toks : Vec<Token>) -> ParseResult<Form> { match all_toks { [ Token::Key(x @ String::from(ALL)), Token::Id(a), Token::Key(String::from(DOT)), toks @ .. ] => { let res = parse(toks); let mkq = make_quant(x, a); apfst(mkq, res) } } }
后续需要修改字符串内容时,只需修改常量定义即可,无需逐一修改所有匹配和使用的地方。
4. 借用匹配优化性能
如果make_quant函数可以接受&str类型参数,还可以通过借用模式避免不必要的String复制:
const ALL: &str = "ALL"; const DOT: &str = "."; fn parse(all_toks : Vec<Token>) -> ParseResult<Form> { match all_toks { [ Token::Key(ref x), Token::Id(a), Token::Key(ref y), toks @ .. ] if x == ALL && y == DOT => { let res = parse(toks); let mkq = make_quant(x, a); // 直接传借用的&str,无需clone apfst(mkq, res) } } }
这种方式通过ref关键字借用Token中存储的String,再通过匹配守卫判断是否等于目标字面量,避免了在模式中构造新的String实例,性能更优。
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

