与 Box 层的模式匹配
Pattern matching with Box layers
我正在尝试解决 Rust 中的表达式问题。我定义了总和类型的术语:
#[derive(Clone, Debug, PartialEq)]
pub enum Term {
True,
False,
Not(Box<Term>),
...
}
编译器和文档说递归项需要 Box
,因为结构不能包含自身(无限回归),仅 &Term
不足以确定项拥有其自身子项。好的,到目前为止一切顺利。
现在我正在尝试编写一个函数,根据运算符的定义来简化术语,例如不正确=错误:
impl Term {
pub fn simplify(self) -> Term {
let a = self.map(Term::simplify);
match a {
Term::Not(Box(Term::True)) => Term::False,
_ => a,
}
}
pub fn map(self, f: fn(Term) -> Term) -> Term {
match self {
Term::True
| Term::False => self,
Term::Not(a) => Term::Not(Box::new(a.map(f))),
_ => panic!(),
}
}
}
但是编译器不喜欢我到目前为止尝试过的任何版本。
Term::Not(Term::True)
无效,因为 Box
需要介于两者之间。
Term::Not(Box::new(Term::True))
在做词时有效,但不能作为模式匹配表达式(不能包含函数调用)。
Term::Not(Box(Term::True))
也无效。
在 Rust 中执行此操作的正确方法是什么?
编译器报如下错误:
cannot match against a tuple struct which contains private fields
。
好的,让我们寻找 Box 的定义(为简单起见,我删除了特征边界):
pub struct Box<_>(Unique<T>, A);
这看起来像错误消息中的元组。但看起来内部值也不是 public(那是错误),所以你不能像这样构造框 (Box(Term::True)
).
我们能做什么?
您可以使用夜间功能 box_patterns
来创建框:
match a {
Term::Not(box Term::True) => Term::False,
_ => a,
}
或者,我们尝试通过取消引用来提取开箱即用的值(此处为 boxed_value
),然后检查内部值:
*boxed_value == Term::True
您可以在 match
:
中将其与 if guards
结合使用
match a {
Term::Not(content) if *content == Term::True => Term::False,
_ => a,
}
我认为这种变体更好,特别是如果您还想从 Term::False
映射到 Term::True
。
我正在尝试解决 Rust 中的表达式问题。我定义了总和类型的术语:
#[derive(Clone, Debug, PartialEq)]
pub enum Term {
True,
False,
Not(Box<Term>),
...
}
编译器和文档说递归项需要 Box
,因为结构不能包含自身(无限回归),仅 &Term
不足以确定项拥有其自身子项。好的,到目前为止一切顺利。
现在我正在尝试编写一个函数,根据运算符的定义来简化术语,例如不正确=错误:
impl Term {
pub fn simplify(self) -> Term {
let a = self.map(Term::simplify);
match a {
Term::Not(Box(Term::True)) => Term::False,
_ => a,
}
}
pub fn map(self, f: fn(Term) -> Term) -> Term {
match self {
Term::True
| Term::False => self,
Term::Not(a) => Term::Not(Box::new(a.map(f))),
_ => panic!(),
}
}
}
但是编译器不喜欢我到目前为止尝试过的任何版本。
Term::Not(Term::True)
无效,因为 Box
需要介于两者之间。
Term::Not(Box::new(Term::True))
在做词时有效,但不能作为模式匹配表达式(不能包含函数调用)。
Term::Not(Box(Term::True))
也无效。
在 Rust 中执行此操作的正确方法是什么?
编译器报如下错误:
cannot match against a tuple struct which contains private fields
。
好的,让我们寻找 Box 的定义(为简单起见,我删除了特征边界):
pub struct Box<_>(Unique<T>, A);
这看起来像错误消息中的元组。但看起来内部值也不是 public(那是错误),所以你不能像这样构造框 (Box(Term::True)
).
我们能做什么?
您可以使用夜间功能 box_patterns
来创建框:
match a {
Term::Not(box Term::True) => Term::False,
_ => a,
}
或者,我们尝试通过取消引用来提取开箱即用的值(此处为 boxed_value
),然后检查内部值:
*boxed_value == Term::True
您可以在 match
:
if guards
结合使用
match a {
Term::Not(content) if *content == Term::True => Term::False,
_ => a,
}
我认为这种变体更好,特别是如果您还想从 Term::False
映射到 Term::True
。