Reputation: 16630
I'm working on a quad tree. Using a closure to determine when a region should be split seems like a good idea.
pub fn split_recursively(&mut self, f: |Rect| -> bool) {
...
self.children.as_mut().map(|children| {
children.nw.split_recursively(f);
children.ne.split_recursively(f);
children.sw.split_recursively(f);
children.se.split_recursively(f);
});
}
The above is what I have tried, but I get
error: cannot move out of captured outer variable children.se.split_recursively(f);
For each of the four children.
I then tried wrapping the closure in a RefCell
fn split_recursively(&mut self, f: &RefCell<|Rect| -> bool>)
and calling it
let should_split = (*f.borrow_mut())(self.rect);
but Rust doesn't like that either:
error: closure invocation in a
&
reference
I know how to work around this by passing a function pointer and &mut to a rng (because splitting should in part depend on randomness), but a closure would be more elegant. Is there any way to get this to work with a closure? If not, would it be possible with unboxed closures?
Upvotes: 3
Views: 1898
Reputation: 1600
Unboxed closures do work but they are currently feature-gated and add complexity.
#![feature(unboxed_closures)]
use std::ops::Fn;
fn main() {
let f = |&: x: uint| println!("Recurse {}!", x);
recursive(&f, 0);
}
fn recursive(f: &Fn<(uint,), ()>, depth: uint) {
if depth < 10 {
f.call((depth,)); // Cannot be invoked like f(depth) currently.
recursive(f, depth + 1);
} else {
()
}
}
Searching around, I found an easy solution. Just call the closure in a closure:
fn main() {
let f = |x: uint| println!("Recurse {}!", x);
recursive(f, 0);
}
fn recursive(f: |uint| -> (), depth: uint) {
if depth < 10 {
f(depth);
recursive(|x| f(x), depth + 1);
} else {
()
}
}
This has a performance impact compared to unboxed closures but it's definitely easier to read. Your choice.
Upvotes: 5