// 定义树节点的 trait
trait TreeNode {
type Data;
fn get_data(&self) -> &Self::Data;
fn children(&self) -> &[Box<dyn TreeNode>];
}
// 具体的树节点实现
struct TreeInnerNode<T> {
data: T,
children: Vec<Box<dyn TreeNode>>,
}
impl<T> TreeInnerNode<T> {
fn new(data: T) -> Self {
TreeInnerNode {
data,
children: Vec::new(),
}
}
}
impl<T> TreeNode for TreeInnerNode<T> {
type Data = T;
fn get_data(&self) -> &Self::Data {
&self.data
}
fn children(&self) -> &[Box<dyn TreeNode>] {
&self.children
}
}
// 根节点结构
struct Tree<T> {
root: Option<Box<dyn TreeNode>>,
}
impl<T> Tree<T> {
fn new() -> Self {
Tree { root: None }
}
fn set_root(&mut self, node: Box<dyn TreeNode>) {
self.root = Some(node);
}
// 遍历操作
fn traverse<F>(&self, f: &mut F)
where
F: FnMut(&dyn TreeNode),
{
if let Some(ref root) = self.root {
self._traverse(root, f);
}
}
fn _traverse<F>(&self, node: &dyn TreeNode, f: &mut F)
where
F: FnMut(&dyn TreeNode),
{
f(node);
for child in node.children() {
self._traverse(child, f);
}
}
// 查找操作
fn find<F>(&self, f: &F) -> Option<&dyn TreeNode>
where
F: Fn(&dyn TreeNode) -> bool,
{
if let Some(ref root) = self.root {
if (f)(root) {
return Some(root);
}
for child in root.children() {
if let Some(result) = self.find_in_subtree(child, f) {
return Some(result);
}
}
}
None
}
fn find_in_subtree<F>(&self, node: &dyn TreeNode, f: &F) -> Option<&dyn TreeNode>
where
F: Fn(&dyn TreeNode) -> bool,
{
if (f)(node) {
return Some(node);
}
for child in node.children() {
if let Some(result) = self.find_in_subtree(child, f) {
return Some(result);
}
}
None
}
}
类型一致性和灵活性问题处理
- 关联类型:通过在
TreeNode
trait 中定义 type Data
,使得每个实现 TreeNode
的具体类型可以有自己的数据类型,保证了灵活性。同时,通过 get_data
方法返回 &Self::Data
,保证了获取数据类型的一致性。
- trait 对象:在
TreeInnerNode
中,children
字段的类型是 Vec<Box<dyn TreeNode>>
,这允许节点的子节点可以是任何实现了 TreeNode
trait 的类型,极大地增加了灵活性。在遍历和查找操作中,通过 &dyn TreeNode
统一处理不同类型的节点,保证了操作的一致性。