Skip to content

Instantly share code, notes, and snippets.

@glycerine
Forked from nikomatsakis/gist:6427775
Last active December 22, 2015 12:49
Show Gist options
  • Save glycerine/6475304 to your computer and use it in GitHub Desktop.
Save glycerine/6475304 to your computer and use it in GitHub Desktop.
// how can we do a tree in Rust, where each node
// tells its children to update, and in turn, the
// child may update the parent?
//
// The following example illustrates the technique. Notice how we
// can't let the children have full backpointers to
// parent nodes, and instead have to have them point
// back to parent.data. Otherwise the two paths
// (parent) and (parent->child) overlap, and modifying
// parent could unsafely clobber (parent->child) use.
//
// Instead deploy two non-overlapping paths,
// (parent->data) and (parent->child), which is fine.
//
// And if this doesn't work for you, you can always fall
// back to @ managed pointers instead. But there's no free lunch. You
// pay an efficiency price for @ flexibility, in terms of
// ref-counting and cycle detection.
struct TreeData {
last: int
}
struct Tree<'self> {
children: ~[~Tree<'self>],
func: &'self fn(&mut TreeData, int) -> int,
data: TreeData
}
impl<'self> Tree<'self> {
fn update_children(&mut self, val: int) -> int {
for s in self.children.mut_iter() {
(s.func)(&mut self.data, 7);
}
return 5 + val;
}
}
fn square(parent : &mut TreeData, x: int) -> int {
let res = x * x;
parent.last = res;
res
}
fn cube(parent : &mut TreeData, x: int) -> int {
let res = x * x * x;
parent.last = res;
res
}
fn main() {
let child = ~Tree {
children: ~[],
func: square,
data: TreeData {last: 0},
};
let mut parent = ~Tree {
children: ~[child],
func: square,
data: TreeData {last: 0},
};
let cv = parent.update_children(3);
printfln!("current value after parent.update_children() is %?", cv);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment