【问题标题】:Store a vec of references to objects in another data structure将对象的 vec 引用存储在另一个数据结构中
【发布时间】:2022-01-25 12:37:34
【问题描述】:

编译以下代码时:

pub enum NodeType {
    None,
    Node(Box<Node>),
}

pub struct Node {
    next: NodeType,
}

impl Node {
    fn traverse_recursively<F>(&self, depth: usize, f: &mut F)
    where
        F: FnMut(&Node, usize),
    {
        f(self, depth);

        match &self.next {
            NodeType::None => {}
            NodeType::Node(node) => {
                node.traverse_recursively(depth + 1, f);
            }
        }
    }

    pub fn visit_all<F>(&self, f: &mut F)
    where
        F: FnMut(&Node, usize),
    {
        self.traverse_recursively(1, f);
    }
}

pub fn create_small_recursive_structure() -> Node {
    Node {
        next: NodeType::Node(Box::new(Node {
            next: NodeType::Node(Box::new(Node { next: NodeType::None })),
        })),
    }
}

#[test]
fn test_so() {
    let parent = create_small_recursive_structure();

    let mut visited = Vec::new();

    parent.visit_all(&mut |node, depth| {
        visited.push((node, depth));
    });
}

编译器给我以下错误:

error[E0521]: borrowed data escapes outside of closure
  --> src/so_question.rs:50:9
   |
47 |     let mut visited = Vec::new();
   |         ----------- `visited` declared here, outside of the closure body
48 | 
49 |     parent.visit_all(&mut |node, depth| {
   |                            ---- `node` is a reference that is only valid in the closure body
50 |         visited.push((node, depth));
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `node` escapes the closure body here

我发现了一个类似的问题here,但解决方案对我没有帮助。 IE。我的闭包参数已经没有类型,我通过添加和删除类型进行了实验,但似乎没有帮助。

为了临时存储对树结构中节点的引用向量,我需要做什么?目的是让向量比节点结构更短。为编译器添加一对额外的括号来强调这一点并没有帮助。

谢谢!

【问题讨论】:

    标签: rust closures borrow-checker ownership


    【解决方案1】:

    您需要指定生命周期,以便编译器知道引用的生命周期与self 的生命周期相同:

    pub enum NodeType {
        None,
        Node(Box<Node>),
    }
    
    pub struct Node {
        next: NodeType,
    }
    
    impl Node {
        fn traverse_recursively<'s, F>(&'s self, depth: usize, f: &mut F)
        where
            F: FnMut(&'s Node, usize),
        {
            f(self, depth);
    
            match &self.next {
                NodeType::None => {}
                NodeType::Node(node) => {
                    node.traverse_recursively(depth + 1, f);
                }
            }
        }
    
        pub fn visit_all<'s, F>(&'s self, f: &mut F)
        where
            F: FnMut(&'s Node, usize),
        {
            self.traverse_recursively(1, f);
        }
    }
    
    pub fn create_small_recursive_structure() -> Node {
        Node {
            next: NodeType::Node(Box::new(Node {
                next: NodeType::Node(Box::new(Node { next: NodeType::None })),
            })),
        }
    }
    
    
    #[test]
    fn test_so() {
        let parent = create_small_recursive_structure();
    
        let mut visited = Vec::new();
    
        parent.visit_all(&mut |node: &Node, depth| {
            visited.push((node, depth));
        });
    }
    
    

    Playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      相关资源
      最近更新 更多