Я пытаюсь определить рекурсивную структуру, похожую на связанный список для обхода дерева. Узел имеет некоторые данные и доступ к своему родителю. Дочерний узел должен взаимно заимствовать своего родителя, чтобы обеспечить монопольный доступ, и освободить его после удаления. Я могу определить эту структуру, используя неизменяемые ссылки, но не тогда, когда я делаю родительскую ссылку изменяемой. Когда я делаю родительскую ссылку изменяемой, меня сбивает с толку ошибка компилятора, и я ее не понимаю.
Как я могу определить время жизни такой рекурсивной структуры с изменяемой родительской ссылкой?
Вот минимальный пример. Это компилируется, но использует ссылку только для чтения:
struct Node<'a> {
// Parent reference. `None` indicates a root node.
// I want this to be a mutable reference.
pub parent: Option<&'a Node<'a>>,
// This field just represents some data attached to this node.
pub value: u32,
}
// Creates a root node
// I use a static lifetime since there's no parent for the root so there are no constraints there
fn root_node(value: u32) -> Node<'static> {
Node {
parent: None,
value,
}
}
// Creates a child node
// The lifetimes indicates that the parent must outlive its child
fn child_node<'inner, 'outer: 'inner>(
parent: &'inner mut Node<'outer>,
value: u32,
) -> Node<'inner> {
Node {
parent: Some(parent),
value,
}
}
// An example function using the struct
fn main() {
let mut root = root_node(0);
let mut c1 = child_node(&mut root, 1);
let mut c2 = child_node(&mut c1, 2);
{
let mut c3 = child_node(&mut c2, 3);
let c4 = child_node(&mut c3, 4);
let mut cur = Some(&c4);
while let Some(n) = cur {
println!("{}", n.value);
cur = n.parent;
}
}
{
let c5 = child_node(&mut c2, 5);
let mut cur = Some(&c5);
while let Some(n) = cur {
println!("{}", n.value);
cur = n.parent;
}
}
println!("{}", c2.value);
}
Площадка для ржавчины: неизменный справочник
Мне нужна изменяемая ссылка, поэтому я попытался заменить структуру Node
, чтобы использовать изменяемую ссылку:
struct Node<'a> {
// Parent reference. `None` indicates a root node.
// I want this to be a mutable reference.
pub parent: Option<&'a mut Node<'a>>,
// This field just represents some data attached to this node.
pub value: u32,
}
Но тогда я получаю следующую ошибку:
error[E0623]: lifetime mismatch
--> src/main.rs:25:22
|
21 | parent: &'inner mut Node<'outer>,
| ------------------------
| |
| these two types are declared with different lifetimes...
...
25 | parent: Some(parent),
| ^^^^^^ ...but data from `parent` flows into `parent` here
Площадка для ржавчины: изменяемая ссылка
Я не понимаю взаимосвязи между изменчивостью и потоком данных в поле. В неизменяемом случае я уже требовал, чтобы функции передавали изменяемые / исключительные ссылки. Я пробовал различные комбинации жизней (используя одну жизнь, меняя их отношения вспять и т. Д.), Но безуспешно.
head.next.next
и(head.next).next
). - person Shepmaster   schedule 12.02.2020c3
он заимствуетc2
(а вместе с нимc1
иroot
), поэтому вы не можете получить к ним доступ, покаc2
не будет удален, и поэтому вы не должны иметь возможность использовать их псевдонимы (по крайней мере, это цель). - person Demurgos   schedule 12.02.2020