Ich versuche, eine DAG zu erstellen und zu durchlaufen. Es scheint zwei mögliche Ansätze zu geben: Verwenden Sie Rc<RefCell<Node>>
für Kanten, oder verwenden Sie einen Arena-Allokator und einen Code von unsafe
. (See details here.)Sicheres Durchlaufen eines gerichteten azyklischen Graphen
Ich bin für das ehemalige entscheiden, aber Schwierigkeiten haben, um die Grafik zu seinen Rändern durchqueren, wie jeder borrow eines Kindes Knoten verlässt sich leiht seinen Eltern:
use std::cell::RefCell;
use std::rc::Rc;
// See: https://aminb.gitbooks.io/rust-for-c/content/graphs/index.html,
// https://github.com/nrc/r4cppp/blob/master/graphs/src/ref_graph.rs
pub type Link<T> = Rc<RefCell<T>>;
pub struct DagNode {
/// Each node can have several edges flowing *into* it, i.e. several owners,
/// hence the use of Rc. RefCell is used so we can have mutability
/// while building the graph.
pub edge: Option<Link<DagNode>>,
// Other data here
}
// Attempt to walk down the DAG until we reach a leaf.
fn walk_to_end(node: &Link<DagNode>) -> &Link<DagNode> {
let nb = node.borrow();
match nb.edge {
Some(ref prev) => walk_to_end(prev),
// Here be dragons: the borrow relies on all previous borrows,
// so this fails to compile.
None => node
}
}
ich das ändern könnte Referenz-Zähler, dh
aber stoßen die Referenz zählt jedes Mal, wenn Sie einen Knoten durchqueren scheint wie der Hack. Was ist der idiomatische Ansatz hier?
Haben Sie dieses http://cglab.ca/~abeinges/blah/too-many-lists/book/fourth-iteration.html#iter gelesen? Obwohl es sich um 'Rc'-Warteschlangen handelt, kann es Ihnen wirklich helfen. – aSpex
... Wenn ich den Abschnitt richtig lese, lief der Autor mit dem Gesicht voran in dasselbe Problem, das ich habe und gab auf. "Rc hat uns wirklich wirklich gescheitert." –
@MattKline: Das ist eigentlich "Jedenfalls gebe ich Iter und IterMut auf. Wir könnten sie machen, aber äh.", So ist es Gankros Meinung möglich, aber vielleicht nicht elegant. –