我有一个有向图数据结构,我发现自己在与模式匹配作斗争以进行简单的内省(introspection)。有没有更好的办法?
除了多个 child 之外,我的结构还允许多个 parent :
pub enum NodePtr {
Terminal(i32),
Node(Rc<RefCell<Node>>),
}
pub struct Node {
children: Vec<NodePtr>,
parents: Vec<Weak<RefCell<Node>>>,
}
这是我可以设计的最简单的代码来断言已按预期建立了单个父子关系:fn example(parent: NodePtr, child: NodePtr) {
if let NodePtr::Node(parent_rc) = &parent {
if let NodePtr::Node(child_rc) = &child {
assert_eq!(parent_rc.borrow().children.len(), 1);
if let Option::Some(node_ptr) = parent_rc.borrow().children.get(0) {
if let NodePtr::Node(rc) = node_ptr {
assert!(Rc::ptr_eq(rc, child_rc));
} else {
assert!(false);
}
} else {
assert!(false);
}
assert_eq!(child_rc.borrow().parents.len(), 1);
if let Option::Some(weak) = child_rc.borrow().parents.get(0) {
if let Some(rc) = weak.upgrade() {
assert!(Rc::ptr_eq(&rc, parent_rc));
} else {
assert!(false);
}
} else {
assert!(false);
}
} else {
assert!(false);
}
} else {
assert!(false)
};
}
Full working example感觉就像我必须经历这么多匹配才能得到我想要的。我是否错过了更好的方式或不同的思维方式?
最佳答案
It feels like I have to wade through so much matching to get at what I want. Am I missing some better way or perhaps a different way of thinking?
您可以在实用函数后面抽象出琐碎的模式匹配,例如:
impl NodePtr {
/// Returns Some if NodePtr is a Node, None otherwise.
fn as_node(&self) -> Option<&Rc<RefCell<Node>>> {
match self {
NodePtr::Node(rc) => Some(rc),
_ => None,
}
}
}
这允许您替换 if let NodePtr::Node(foo) = foo { ... } else { assert!(false); }
与 let foo = foo.as_node().unwrap()
.您也可以使用foo.unwrap()
而不是整个 if let Some(foo) = foo { ... } else { assert!(false); }
堵塞。最后,您不需要对 x.get(n)
进行模式匹配。 , 你可以使用 x[n]
或 &x[n]
.应用所有这些会将您的代码压缩为以下内容:
// prove parent & child relationship
let parent_rc = parent.as_node().unwrap();
let child_rc = child.as_node().unwrap();
assert_eq!(parent_rc.borrow().children.len(), 1);
let node_ptr = &parent_rc.borrow().children[0];
assert!(Rc::ptr_eq(node_ptr.as_node().unwrap(), child_rc));
assert_eq!(child_rc.borrow().parents.len(), 1);
let weak = &child_rc.borrow().parents[0];
assert!(Rc::ptr_eq(&weak.upgrade().unwrap(), parent_rc));
Playground还有一个单独的问题是,您的类型是否可以被结构化以避免如此多的运行时检查和 panic 的可能性。我建议查看现有的 crate 以构建 DAG。
关于data-structures - 如何断言/内省(introspection)嵌套的递归结构/枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64848101/