Closed
Description
Proposal
Problem statement
Currently there is no owning analog to the chars iterator. In most contexts this has no real effect, as char
is Copy
, but it disables some cases where one wants to pass ownership of the underlying String
along with the iterator.
Motivating example
Implementing the following function requires some gymnastics.
fn get_chars() -> impl Iterator<Item=char> {
let s = format!("for one reason or another, you have a String");
s.chars().filter(|c| ['a','e','i','o','u'].contains(c))
// error[E0597]: `s` does not live long enough
}
Solution sketch
If into_chars
existed, the above function would be simple to write.
fn get_chars() -> impl Iterator<Item=char> {
let s = format!("for a very good reason, you have a String");
s.into_chars().filter(|c| ['a','e','i','o','u'].contains(c))
}
Alternatives
It is relatively straightforward to write an owning chars iterator outside of std
. As a struct:
struct IntoChars {
string: String,
position: usize,
}
impl Iterator for IntoChars {
type Item = char;
fn next(&mut self) -> Option<char> {
let c = self.string[self.position..].chars().next()?;
self.position += c.len_utf8();
Some(c)
}
}
As a closure:
fn into_chars(s: String) -> impl Iterator<Item = char> {
let mut i = 0;
std::iter::from_fn(move ||
if i < s.len() {
let c = s[i..].chars().next().unwrap();
i += c.len_utf8();
Some(c)
} else {
None
}
)
}