Using Chars::peekable() without fighting the borrow checker

I'm new to rust and struggling with this:

use std::iter::Peekable;
use std::str::Chars;

struct Result<'a> {
    src: Chars<'a>,
}

impl<'a> Result<'a> {
    fn peek_and_consume(&mut self) {
        let chars = &mut self.src;
        for c in chars {
            println!("current: {}", c);
            // println!("next: {}", chars.peekable().peek().unwrap());
        }
    }

    fn new(s: &'a str) -> Result<'a> {
        Result { src: s.chars() }
    }
}

fn main() {
    let mut result = Result::new("ABCDEFGHIJK");
    result.peek_and_consume();
}

I can't get the following code to build with the commented line un-commented, and I don't understand why. Could someone suggest a way to fix this?

For context: I wanted to store this Chars iterator in the struct so I could easily refer to it in different methods for parsing some complicated structure in my actual code, by advancing with next() and looking forward with peekable.

Because you are trying to achieve shared mutability. You can't get another iterator (the peekable) to mutate the state of the original, while the original iterator is still being mutated (by the for loop).

If you need to peek, you should just store the peekable in the first place.

Furthermore, you must rewrite the loop manually to shorten the borrow of the iterator between iterations.

1 Like

That makes sense, thanks for taking the time to correct this. I didn't realise that the peekable itself can have the same functionality (consuming next() call). Perfect.
:pray:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.