Loops with accumulated state confuse me
â Rust đ 2026-04-15 đ¤ surdeus đī¸ 5I 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.
Maybe I shouldn't admit that... âŠī¸
2 posts - 2 participants
đˇī¸ Rust_feed