Skip to content

Implement into_chars for String #268

Closed
@al-yisun

Description

@al-yisun

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
        }
    )
}

Links and related work

Discussion on irlo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions