2013-12-20 7 views
15

Ich hätte gerne Strukturmitglieder, die ihre Eltern kennen. Das ist ungefähr das, was ich versuche zu tun:Welche Lebenszeiten verwende ich, um Rust-Strukturen zu erstellen, die sich zyklisch aufeinander beziehen?

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); 
} 

Ich habe versucht, den Compiler mit Leben zu beruhigen, ohne vollständig zu verstehen, was ich tat.

Hier ist die Fehlermeldung, die ich auf bin stecken:

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 

, dass einige Sinn macht, aber ich bin nicht sicher, wohin man von hier zu gehen.

Antwort

9

Es ist nicht möglich, zyklische Strukturen mit geliehenen Zeigern zu erstellen.

Es gibt keine gute Art und Weise des Erreichens von zyklischen Datenstrukturen zur Zeit; Die einzigen wirklichen Lösungen sind:

  1. Verwenden Referenzzählung mit Rc<T> mit einer cyclischen Struktur mit Rc::new und Rc:downgrade. Lesen Sie rc module documentation und achten Sie darauf, keine zyklischen Strukturen mit starken Referenzen zu erstellen, da dies zu Speicherlecks führen kann.
  2. Verwenden Sie rohe/unsichere Zeiger (*T).
+0

Danke; sehr gut zu wissen. Ich denke, ich werde sehen, ob ich die Smarts im Child bis zum Parent neu gestalten kann und die Notwendigkeit für den Parent-Pointer los werde. – Grumdrig

+0

Eigentlich ist diese Idee ein kleiner Albtraum und '* T' scheint genau das zu sein, was ich will. Aber ich kann es nicht benutzen, um auf die Mitglieder von Parent zuzugreifen. Wenn ich versuche, 'c1.parent.i' zu verwenden (vorausgesetzt, dass Parent ein' i: int'-Feld hat, das in meinem Beispiel nicht gezeigt wird), bekomme ich 'error: versuchter Zugriff des Feldes 'i' auf den Typ '* Parent', aber es wurde kein Feld mit diesem Namen gefunden. Ich kann nicht viel Information über diese Bestien finden. – Grumdrig

+1

Macht nichts. Rust erhöht nicht automatisch gefährliche Zeiger, so dass '(* c1.parent) .i' funktioniert (in einem' unsicheren' Block). – Grumdrig