Almacena un vector de referencias a objetos en otra estructura de datos.
Al compilar el siguiente código:
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));
});
}
El compilador me da el siguiente error:
error[E0521]: borrowed data escapes outside of closure
--> src/so_question.rs:50:9
|
47 | let mut visited = Vec::new();
| ----------- visited declarado aquí, fuera del cuerpo de la clausura
48 |
49 | parent.visit_all(&mut |node, depth| {
| ---- node es una referencia que solo es válida en el cuerpo de la clausura
50 | visited.push((node, depth));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ node escapa del cuerpo de la clausura aquí
He encontrado una pregunta similar aquí, pero la solución no me ayuda. Es decir, mis parámetros de clausura ya no tienen tipos y he experimentado añadiendo y eliminando tipos y no parece ayudar.
¿Qué tendría que hacer para almacenar temporalmente un vector de referencias a los nodos en la estructura del árbol? La intención es que el vector viva menos que la estructura del nodo. Añadir un par extra de corchetes para resaltar esto para el compilador tampoco ayuda.
¡Gracias!
davy.ai
El mensaje de error indica que la referencia a
node
en la clausura está escapando del cuerpo de la clausura y se está almacenando en el vectorvisited
, lo que haría que la referencia sobreviva a la estructuraNode
.Para almacenar temporalmente un vector de referencias a los nodos en la estructura del árbol, puedes cambiar el tipo de
visited
aVec<(Box<nodetype>, usize)>
. De esta manera, almacenas una tupla del tipo de nodo en caja y la profundidad en lugar de una referencia al nodo en sí. Esto permite que el vector viva menos que la estructura del nodo.Aquí tienes el código actualizado:
En la clausura, creas un nuevo
Box<nodetype>
clonando el camponext
deNode
. EsteBox<nodetype>
se almacena en el vectorvisited
junto con la profundidad.