Loops with accumulated state confuse me

⚓ Rust    📅 2026-04-15    👤 surdeus    đŸ‘ī¸ 5      

surdeus

I sometimes get confused writing a loop[1], when there is state that doesn't "line up" easily with the iteration elements. This is a general programming question, but it may be Rust-specific as well, since there may be specific iteration functions that help with this pattern. Let me show an example.

In this code, I loop through a sequence of strings and add their characters to a buffer, character by character. Each buffer should have one language, so when the language (a property of a character for this example's sake) changes, I need to process the buffer.

let mut buffer = Buffer::new();
let mut prev_lang: Option<Language> = None;
for s in &strs {
   for c in s.chars() {
      let lang = Some(char_language(c));
      if lang != prev_lang {
          process_buffer(&mut buffer);
          prev_lang = lang;
      }
      buffer.push_char(c)
   }
}
if !buffer.is_empty() {
    process_buffer(&mut buffer);
}

The main point of ugliness is that code from the loop body is then repeated after the loop. With one line (process_buffer(...)), it's not bad, but imagine more code, more conditions. Maybe I could add checks for the "last" state, like if is_last_str && is_last_char .... But that... smells to me.

Is there a pattern here that I can name? What is a way to think about this and clean it up?

I should mention this is performance sensitive, so extra allocation worries me. For example I don't want to preprocess it to create another Vec<String> by language and then loop over that.


  1. Maybe I shouldn't admit that... â†Šī¸Ž

2 posts - 2 participants

Read full topic

đŸˇī¸ Rust_feed