我正在try 在Rust中创建一个简单的XML编写器,首先在内存中构建一个标签树.

在下面的函数add_child中,我希望将新创建的子元素添加到当前元素的子元素列表中,然后返回该子元素,以便调用者可以将其他子元素添加到该子元素中.但我不能,因为这样子元素就归载体所有了.

在Rust中做这类事情的"惯用"方式是什么?

我想我可以让我的tag.rs库的消费者自己操作 struct 中的子列表,但是实现细节并没有整齐地包含在函数中.

有没有其他更好的方法来做到这一点?

// tag.rs
use std::collections::HashMap;

pub struct Tag<'a> {
    name: &'a str,
    attributes: HashMap<&'a str, &'a str>,
    children: Vec<Tag<'a>>,
}

impl<'a> Tag<'a> {
    pub fn new(name: &'a str) -> Self {
        Self {
            name,
            attributes: HashMap::new(),
            children: vec![],
        }
    }

    pub fn add_child(&mut self, name: &'a str) -> Self {
        let mut child = Self::new(name);
        self.children.push(child); // `child` moved here
        child // <-- Error: use of moved value: `child`        
    }

    pub fn add_attribute(&mut self, key: &'a str, value: &'a str) {
        self.attributes.insert(key, value);
    }
}

推荐答案

您可以返回对最后一个元素的可变引用:

pub fn add_child(&mut self, name: &'a str) -> &mut Self {
    let mut child = Self::new(name);
    self.children.push(child); // `child` moved here
    self.children.last_mut().unwrap()
}

Rust相关问答推荐

在不重写/专门化整个函数的情况下添加单个匹配手臂到特征的方法?

如何删除Mac Tauri上的停靠图标?

如何计算迭代器适配器链中过滤的元素的数量

将一个泛型类型转换为另一个泛型类型

为什么特征默认没有调整大小?

在没有任何同步的情况下以非原子方式更新由宽松原子操作 Select 的值是否安全?

Rust编译器通过哪些规则来确保锁被释放?

Rust 打包在 .deb 中

为什么这段 Rust 代码会在没有递归或循环的情况下导致堆栈溢出?

max(ctz(x), ctz(y)) 有更快的算法吗?

我如何取消转义,在 Rust 中多次转义的字符串?

有没有办法通过命令获取 Rust crate 的可安装版本列表?

为什么数组不像向量那样在 for 块之后移动?

为什么 i32 Box 类型可以在 Rust 中向下转换?

为什么允许重新分配 String 而不是 *&String

为什么可以从闭包中返回私有 struct

制作嵌套迭代器的迭代器

使用 rust-sqlx/tokio 时如何取消长时间运行的查询

如何在没有 `make_contiguous()` 的情况下对 VecDeque 进行排序或反转?

如何制作具有关联类型的特征的类型擦除版本?