How to Box an Iterator?


#1

How to make this function work?

fn BoxIt(s: &str) -> Box<Iterator<Item = char>> {
    return Box::new(s.chars());
}

I guess I should associate the lifetime of the String and the Chars object, do I?

And more how to complete this function ?

fn BoxIt2<T: Iterator<Item = char>>(s: T) -> Box<Iterator<Item = char>> {
    return Box::new(s);
}

Actually,I ask above questions,because I want to make a struct:

struct CharStream {
    stream: Box<Iterator<Item = char>>,
    current: Option<char>,
}

Is it correct to use Box here?


#2

Same idea for BoxIt and BoxIt2, which as you said is to associate lifetime parameters:

fn BoxIt<'a>(s: &'a str) -> Box<Iterator<Item = char> + 'a> {
    return Box::new(s.chars());
}

fn BoxIt2<'a, T: Iterator<Item = char> + 'a>(s: T) -> Box<Iterator<Item = char> + 'a> {
    return Box::new(s);
}

As for CharStream, you can make it generic to avoid boxing:

struct CharStream<I: Iterator<Item = char>> {
    stream: I,
    current: Option<char>,
}

#3

You can explicitly tell the compiler your iterator lives as long as the input string by adding a lifetime annotation. I’ve amended your first example to say that the thing inside the box is both an iterator of characters, and has a lifetime of 'a (the same as the input string).

fn box_it<'a>(s: &'a str) -> Box<Iterator<Item = char> + 'a> {
    Box::new(s.chars())
}

It’s fairly uncommon to use boxed iterators in Rust, it adds an extra level of indirection, unnecessary allocations, and it means the compiler isn’t able see inside the box when doing optimisation.

Instead, you’ll typically make CharStream generic over any iterator of chars. So your CharStream might look something like this:

struct CharStream<I: Iterator<Item = char>> {
    stream: I,
    current: Option<char>,
}

That way the iterator is stored in-line inside the CharStream and is more idiomatic.

EDIT: Damnit, looks like @vitalyd beat me to it :joy:


#4

You elaborated a lot more than I did, so :+1:, and good thing we wrote the same thing :slight_smile:


#5

Thanks.
I just knew the &'a xxx syntax, but didn’t know + 'a