Какое время жизни я использую для создания структур Rust, которые циклически ссылаются друг на друга?

Я хотел бы иметь членов структуры, которые знают их родителя. Это примерно то, что я пытаюсь сделать:

struct Parent<'me> {
    children: Vec<Child<'me>>,
}

struct Child<'me> {
    parent: &'me Parent<'me>,
    i: i32,
}

fn main() {
    let mut p = Parent { children: vec![] };
    let c1 = Child { parent: &p, i: 1 };
    p.children.push(c1);
}

Я попытался успокоить компилятор со сроками жизни, не понимая, что я делаю.

Вот сообщение об ошибке, на которое я застрял:

error[E0502]: cannot borrow `p.children` as mutable because `p` is also borrowed as immutable
  --> src/main.rs:13:5
   |
12 |     let c1 = Child { parent: &p, i: 1 };
   |                               - immutable borrow occurs here
13 |     p.children.push(c1);
   |     ^^^^^^^^^^ mutable borrow occurs here
14 | }
   | - immutable borrow ends here

Это имеет смысл, но я совсем не уверен, куда идти отсюда.

Ответ 1

Невозможно создать циклические структуры с заимствованными указателями.

В настоящее время нет хорошего способа создания циклических структур данных; единственными реальными решениями являются:

  • Используйте подсчет ссылок с Rc<T> с циклической структурой с Rc::new и Rc:downgrade. Прочитайте документацию rc и будьте осторожны, чтобы не создавать циклические структуры, которые используют сильные ссылки, так как это приведет к утечкам памяти.
  • Используйте необработанные/небезопасные указатели (*T).