微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Rust 迭代器遍历 `Rc`s 层次结构的生命周期

如何解决Rust 迭代器遍历 `Rc`s 层次结构的生命周期

我有一个表示分层数据结构的 Rust 结构,每个结构都包含一个 Vec<Rc<Self>> 来创建分层结构。我想创建一个迭代器,从给定的节点开始,迭代 Rc 到层次结构的每个成员。 Node 结构具有生命周期参数 'a,因为整个层次结构从整个层次结构所基于的文本文档中引用一些 &'a str(包含在 NodeDetail<'a> 中)。

pub struct Node<'a> {
    pub detail: NodeDetail<'a>,pub children: Vec<Rc<Self>>,}

impl<'a> Node<'a> {

    // Returns an iterator over `Rc`s to all the children
    pub fn iter(&self) -> Box<(dyn Iterator<Item=Rc<Self>> + 'static)> {
        let mut ans:Box<(dyn Iterator<Item=Rc<Self>> + 'static)> = Box::new(std::iter::empty());

        for c in self.children.iter() {
            ans = Box::new(ans.chain(std::iter::once(c.clone())));
            ans = Box::new(ans.chain(c.iter()));
        }

        ans
    }

}

通过这次尝试,我收到了这个错误

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/model/updm/impl_common.rs:23:40
   |
23 |             ans = Box::new(ans.chain(c.iter()));
   |                                        ^^^^
   |
note: first,the lifetime cannot outlive the lifetime `'a` as defined on the impl at 5:6...
  --> src/model/updm/impl_common.rs:5:6
   |
5  | impl<'a> super::UpdmCommon<'a> {
   |      ^^
note: ...so that the types are compatible
  --> src/model/updm/impl_common.rs:23:40
   |
23 |             ans = Box::new(ans.chain(c.iter()));
   |                                        ^^^^
   = note: expected `&UpdmCommon<'_>`
              found `&UpdmCommon<'a>`
   = note: but,the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
  --> src/model/updm/impl_common.rs:23:19
   |
23 |             ans = Box::new(ans.chain(c.iter()));
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected `Box<(dyn Iterator<Item = Rc<UpdmCommon<'a>>> + 'static)>`
              found `Box<dyn Iterator<Item = Rc<UpdmCommon<'a>>>>`

我认为在某种程度上混淆了 Node 结构是通用的生命周期与特定于迭代器的生命周期。我正在克隆 Rc 以便迭代器的 Item 被拥有并且具有 'static 生命周期。我认为迭代器本身也应该被拥有,这将使它成为 'static。我首先尝试了 Box<dyn Iterator<Item=Rc<Self>>>,然后添加'static 注释以尝试修复我遇到的第一个错误。有人知道怎么修这个东西吗?谢谢!

解决方法

我想通了。在我寻求帮助后,我会立即尽最大努力进行故障排除。有点像我在按下发送后如何做我最好的电子邮件校对。

事实证明,我需要 Box<(dyn Iterator<Item=Rc<Self>> + 'a)>,现在我想到它是有道理的,因为迭代器不能比整个层次结构所依赖的原始 &'a str 更长寿。

,

您需要将从 iter() 返回的值的生命周期绑定到 &self,并且需要将装箱迭代器转换为 trait 对象。

use std::rc::Rc;

pub struct NodeDetail<'a>(&'a str);

pub struct Node<'a> {
    pub detail: NodeDetail<'a>,pub children: Vec<Rc<Self>>,}

impl<'a> Node<'a> {

    // Returns an iterator over `Rc`s to all the children
    pub fn iter(&'a self) -> Box<(dyn Iterator<Item=Rc<Self>> + 'a)> {
        let mut ans = Box::new(std::iter::empty()) as Box<dyn Iterator<Item=Rc<Self>>>;

        for c in self.children.iter() {
            
            ans = Box::new(ans.chain(std::iter::once(c.clone())));
            ans = Box::new(ans.chain(c.iter()));
        }

        ans
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。