Reputation: 5406
I have a struct:
struct Quads<'a> {
mx: &'a Vec<Vec<u32>>,
xs: &'a mut Peekable<Range<i32>>,
ys: &'a mut Peekable<Range<i32>>,
dx: i32,
dy: i32,
}
I wanted the type of xs
to be Peekable<dyn Iterator<Item = i32>>
, as that would be a natural thing to want in other languages. Is such an idea expressible in Rust?
That is, "a Peekable
of some Iterator
of i32
", not a Peekable
of a specific Iterator
.
Upvotes: 1
Views: 896
Reputation: 60052
The problem with Peekable<dyn Iterator<Item = i32>>
is that dyn Trait
represents a type dynamically (obviously) which means that it is a dynamically sized type. Those cannot be expressed directly as a struct field (except through obscure means).
So @edwardw's comment is the way to go. Putting the iterator in a Box
ensures the field has a fixed size but the iterator itself can be whatever size it wants. Box
also naturally implements Iterator
if the contents implement Iterator
. Here's the changes (also following your lead in your other Q&A that they should be stored directly and not as &mut
references):
struct Quads<'a> {
mx: &'a Vec<Vec<u32>>,
xs: Peekable<Box<dyn Iterator<Item = i32>>>,
ys: Peekable<Box<dyn Iterator<Item = i32>>>,
dx: i32,
dy: i32,
}
Which you can then create via Box::new(0..dx) as Box<dyn Iterator<Item = i32>>
(playground).
If the expected concrete type is Range<i32>
then this probably isn't a problem, but if you did want to store more exotic iterators that require lifetimes, then you may need to add a + 'a
constraint as shown in this answer: How can I make Box<dyn Iterator>
peekable and avoid lifetime errors?
Upvotes: 1