You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无递归且不克隆地将Source转换为Target?

无递归、无克隆实现Source到Target的转换

首先明确结构体定义:

pub struct Source {
    pub name: String,
    pub child: Vec<Source>,
}

pub struct Target {
    pub id: String,
    pub nested: Vec<Target>,
}

解决方案:迭代式深度优先遍历+所有权转移

利用堆上的栈结构模拟递归过程,同时通过Rust的所有权转移机制避免克隆,完全规避栈溢出风险。核心思路是用栈保存待处理的Source节点,以及对应Target父节点的子列表可变引用,逐个转移所有权完成转换:

impl From<Source> for Target {
    fn from(mut source: Source) -> Self {
        // 初始化根节点,直接转移name所有权到id
        let mut root = Target {
            id: source.name,
            nested: Vec::new(),
        };

        // 栈元素:(待处理的Source节点, 对应Target父节点的nested可变引用)
        let mut stack = vec![(source, &mut root.nested)];

        while let Some((mut current_source, parent_nested)) = stack.pop() {
            // 倒序取出子节点压栈(保证遍历顺序和递归DFS一致,无需特定顺序可省略rev())
            for mut child in current_source.child.drain(..).rev() {
                // 创建子Target,转移子Source的name所有权
                let mut child_target = Target {
                    id: child.name,
                    nested: Vec::new(),
                };
                // 将子Source和子Target的nested引用压栈,后续处理其子节点
                stack.push((child, &mut child_target.nested));
                // 将子Target加入父节点的nested列表
                parent_nested.push(child_target);
            }
        }

        root
    }
}

关键细节说明

  1. 所有权转移而非克隆:使用drain(..)获取Source子节点的所有权,同时清空原Vec,完全避免克隆操作,内存效率拉满。
  2. 堆栈替代调用栈:用Vec实现的栈存储待处理节点,堆内存的容量远大于调用栈,彻底解决用户输入深度过大导致的栈溢出问题。
  3. 安全的可变引用:栈中保存的父节点nested可变引用,确保子节点能被正确添加到对应位置,完全符合Rust的借用规则。

内容的提问来源于stack exchange,提问作者newSqlz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:52:31