bzm3r
bzm3r

Reputation: 4605

Why are `Item`s of a `Char` iterator, obtained from calling `chars` on a string slice, not references to `char`s?

Running the following code will cause the compiler to complain that PairedNumbers::get returns (char, char) and not (&char, &char):

use std::iter::{Zip, Cycle, Skip};
use std::str::Chars;

struct PairedNumbers<'a> {
    char_pairs: Zip<Cycle<Chars<'a>>, Skip<Cycle<Chars<'a>>>>,
    counter: usize,
}

impl<'a, 'b: 'a> PairedNumbers<'a> {
    fn new(num_str: &'b str, jump: usize) -> PairedNumbers<'a> {
        PairedNumbers {
            char_pairs: num_str.chars().cycle().zip(num_str.chars().cycle().skip(jump)),
            counter: 0,
        }
    }

    fn get(&'a mut self) -> (&'a char, &'a char) {
        self.counter = self.counter + 1;
        self.char_pairs.next().expect("could not get char pair from unparsed_pairs!")
    }
}

We see that the PairedNumbers struct is initialized by making iterators (Chars to be specific) over the characters of the string slice. Given that &str is a reference to a particular region of memory (I am assuming a contiguous region?), wouldn't Chars really be iterating over references to the the component chars that make up the str? Is Rust's auto-dereferencing at play here?

Upvotes: 0

Views: 458

Answers (1)

Stefan
Stefan

Reputation: 5530

A &str points to an UTF-8 encoded sequence of characters; as they are encoded you cannot get an iterator resulting in references to the decoded characters, the decoded character need to be returned by value.

Also see the Item type of the Iterator impl for std::str::Chars.

Upvotes: 3

Related Questions