Trying to build simple iterator, but confused with borrow checker

Hello,

I have a simple struct that takes a string, splits it on whitespace, and when called next returns the first word and then reassigns remaining words back to the struct field.

Playground Code

When I remove the first element from Vector (as the function documentation suggests) It returns an element T, not the reference or something, but still can't return that value from next() because rust tells me it is borrowed.

Anyone can clear this to me what's going on and how to solve it?

Hint: what would be the full type of the vector? Try replace the Vec<_> with the type you think and see what the compiler says.

Thank you, kind sir. So as I understand when I remove an element and assign it to ret it's still a reference to the part which is in self.current.

I called let ret = split.remove(0).to_string(); before new assignment and it solved an issue because to_string() creates a new string

pub struct Tokenizer {
    current: Option<String>,
}

impl Tokenizer {
    fn new(line: &str) -> Self {
        Tokenizer {
            current: Some(line.to_string()),
        }
    }
}

impl Iterator for Tokenizer {
    type Item = String;

    fn next(&mut self) -> Option<Self::Item> {
        // U could use the clone method to clone a new instance of self current 
       // current is Option<String>
        let mut current = self.current.clone();
        if let Some(ref mut s) = current { // then borrow from the current 
            let mut split: Vec<_> = s.split(' ').collect();
            let ret = split.remove(0);
            if split.is_empty() {
                self.current = None;
            } else {
                self.current = Some(split.join(" "));
            }
            Some(ret.to_string())
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn two_word_string() {
        let mut line = Tokenizer::new(&"Hello World");
        assert_eq!("Hello".to_string(), line.next().unwrap());
        assert_eq!("World".to_string(), line.current.unwrap());
    }
}

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.