Iteration: internal vs external vs generation?

⚓ Rust    📅 2026-02-16    👤 surdeus    👁️ 1      

surdeus

I have a tree of different types of objects, all of which implement a trait Widget. At times I need a way to walk the tree, so one of the methods I defined on the trait was:

pub type WidgetChildIter<'a> = 
    Box<dyn DoubleEndedIterator<Item = Rc<dyn Widget + 'static>> + 'a>;
fn iter_children(&self) -> Option<WidgetChildIter<'_>> { None }

It’s proving difficult to implement this. The different Widget types tend to have different internal structure and the iteration is a combination of if/else and sub-loops. So I thought it might be easier to do an “internal” iterator, like this:

impl Widget for Thingy {
    fn iter_children(&self, f: Box<dyn Fn(&dyn Widget)>) {
        if let Some(br) = self.border_rectangle { f(br) }
        for w in self.components { f(w) }
        ...

It seems easier to write, and read, but it doesn’t seem to be the usual Rust way to iterate. Is the main downside that I then miss out on all the things implemented for Iterator, like the map/filter/zip/etc?

I could add some parameters for reverse direction or stopping early.

From what I can tell a “generator” would combine the best of both worlds, but that is not in stable Rust yet. ?

Any recommendations?

1 post - 1 participant

Read full topic

🏷️ Rust_feed