为什么使用Rust的matches!宏时参数顺序会影响匹配结果?
matches!宏不符合预期的原因
matches!宏的语法为matches!(待匹配表达式, 模式),它的核心作用是判断左侧表达式是否符合右侧给定的模式匹配规则,而非判断两个值是否相等,你遇到的问题完全是因为误用了第二个参数的语义:
- 模式中出现的小写标识符默认是变量绑定规则,而非引用外部同名变量:
你写的matches!(Foo::B, a)中,右侧的a不是你外层定义的Foo::A变量,而是一个全新的绑定变量,该模式会匹配任意值并将其绑定到新的a变量上,因此该判断永远为真,才会输出not expected 2。 - 同理
matches!(a, b)中,右侧的b也是模式内的新绑定变量,无论左侧a是什么枚举值都会匹配成功,因此输出not expected 3。 - 你写的
matches!(a, Foo::A)、matches!(a, Foo::B)用法是正确的,因此输出符合预期。
正确的枚举比较方案
如果你只是需要判断两个枚举值是否相等,推荐两种方案:
- 为枚举派生
PartialEqtrait,直接用==运算符比较:
#[derive(PartialEq)] enum Foo { A, B, } fn main() { let a = Foo::A; let b = Foo::B; if a == Foo::A { println!("expected") } if a == Foo::B { println!("not expected 1") } if Foo::B == a { println!("not expected 2") } if a == b { println!("not expected 3") } }
运行后只会输出expected,符合预期。
- 如果确实需要使用
matches!做匹配,右侧必须写枚举变体字面量,或者通过匹配守卫引用外部变量:
// 需先派生PartialEq if matches!(a, x if x == b) { println!("a等于b") }
如果你把变量定义为const常量,也可以直接出现在模式中:
const B: Foo = Foo::B; if matches!(a, B) { println!("匹配B") }
内容的提问来源于stack exchange,提问作者eldorz
相关产品推荐
相关产品推荐

