There's a problem I keep running into. Say for example I have the following:
fn make_iterator<'a, T>(t: &'a T) -> ///???
where T: SomeTrait
{
/* some complex logic*/
return |i:usize| {
let res = t.method(i);
t.other_method(res)
};
}
A practical example of something like this I am trying:
pub fn iter_concentric_rings<'a>(&'a self, depth: usize)
where
V: Clone + Debug,
E: Clone + Debug,
F: Clone + Debug,
{
BFSIterator::new(self.id(), |depth, &id| {
let v = unsafe { (*self.mesh).vert_handle(id) };
v.iter_verts().map(|h| h.id())
})
}
in either of these cases, the objective is constructing a closure that does something with context it inherits from the broader scope. They exist as a convenience, the caller could simply just define them themselves, it's just tedious and verbose.
You could replace them with macros, and that would work, but I tend to prefer avoiding macros when possible.
If structs were callable you could instead define the functionality as a method of a struct and pass that, allowing you to return a closure like object that is not a closure.
In general, I just don't know how to make these helpers that try to minimize the tedium of defining common patterns of closure definition that are constructed all over my code.
You can use impl Trait
syntax to return a closure.
pub fn return_closure<T>(t: T) -> impl FnOnce(usize) -> T {
move |i: usize| t
}
You may want to return FnOnce
, FnMut
, or Fn
depending on the closure.
Your other example will likely look something like this:
pub fn iter_concentric_rings<'a>(&'a self, depth: usize)
-> BFSIterator<impl Fn(usize, &Id) -> IterVerts + 'a>
You can't make structs callable, but you can make another trait and implement it for closures and certain structs.