rust documentation关于用于模式匹配的 |
运算符没有太多说明。只举了一个例子:
let x = 1;
match x {
1 | 2 => println!("one or two"),
3 => println!("three"),
_ => println!("anything"),
}
与the answer相反的this question ,我注意到以下编译:
struct S(E, usize);
#[derive(Copy, Clone)]
enum E {
P(u8), Q(u8)
}
fn main() {
let x = S(E::P(1), 10);
if let S(E::P(..) | E::Q(..), _) = x {
}
let y = E::P(2);
match (y, y) {
(E::Q(..), E::P(..) | E::Q(..)) => {
}
_ => {}
}
}
在该特定问题中,匹配的是整数,而不是枚举类型的值。整数实现了 std::ops::BitOr 特征,因此子模式会发生冲突。
我的问题是:
- 这是一项功能吗?为什么会编译?为什么它看起来有效?
- 此功能有哪些限制? (例如类型不得实现 BitOr 或类似的)
- 该功能叫什么?用于实现该功能的 AST 节点是什么?即使是编译器实现中 AST 节点类型的名称也比称为“
|
-operator”更好,因为它非常模糊。
最佳答案
Is this a feature? Why does it compile? Why does it seem to work?
在 Rust 1.53 之前,|
只允许在匹配臂的顶层,但从那时起它们被扩展为允许在嵌套模式中使用。所以你所看到的正在按预期工作;只是链接的问答已经过时了。
What are the limitations of this feature? (e.g. type must not implement BitOr or similar)
相反,这不使用 BitOr
运算符,因此适用于可以与多个值匹配的任何类型。请记住,模式匹配采用结构相等,而不是值相等。因此,模式 1 | 2
将匹配 1
或 2
,而如果它使用 BitOr
那么它只会匹配 3
.
就功能而言,这是相当无限的:
Or-patterns are patterns that match on one of two or more sub-patterns (e.g.
A | B | C
). They can nest arbitrarily. Syntactically, or-patterns are allowed in any of the places where other patterns are allowed, with the exceptions oflet
-bindings and function and closure arguments. - Rust Reference
What is the feature called? What is the AST node used to implement the feature called? Even the name of the type of the AST node in the compiler implementation would be a better name to use in discussion than calling it the "|-operator", which is very vague.
原文RFC 2535简单地称为“或模式”,这反射(reflect)在引用文档中。不确定 AST 节点的名称,但 Pattern grammar Rust 引用中只是将 |
链直接作为 Pattern
生成的一部分,而其他类型的模式则推迟到 PatternNoTopAlt
或 没有范围的模式
。
关于rust - 匹配子模式中的或运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72875966/