'Trouble implementing custom IntoIterator trait
I'm new to rust, so forgive me if the question is naive.
I'm trying to build an OS in rust and I'm following this tutorial. The OS doesn't have memory management yet, so the goal is to build an object which is like a vector in that it can be pushed and popped etc, but it lives on the stack. We do this by initializing it with an array of fixed size. It looks like this:
#[derive(Debug)]
pub struct StackVec<'a, T: 'a> {
storage: &'a mut [T],
len: usize
}
impl<'a, T: 'a> StackVec<'a, T> {
pub fn new(storage: &'a mut [T]) -> StackVec<'a, T> {
StackVec {
storage: storage,
len: 0,
}
}
pub fn with_len(storage: &'a mut [T], len: usize) -> StackVec<'a, T> {
if len > storage.len(){
panic!();
}
StackVec{
storage: storage,
len: len
}
}
pub fn capacity(&self) -> usize {
self.storage.len()
}
pub fn into_slice(self) -> &'a mut [T] {
&mut self.storage[0..self.len]
}
// Other functions which aren't relevant for the question.
}
Popping and pushing increases and decreases the len
variable and adds and removes entries from the appropriate place in the array.
Now, we also need to implement the IntoIterator trait. Given that the StackVec
contains a reference to an array, I thought that I could just return an iterator from the underlying array:
impl <'a, T:'a> IntoIterator for StackVec<'a, T> {
type Item = T;
type IntoIter = core::array::IntoIter; // <- Throws "not found in `core::array"
fn into_iter(self) -> Self::IntoIter {
self.into_slice().into_iter()
}
}
But no matter how much I play around with it, it still doesn't want to compile. I can't find a way to express using types that into_iter
should return the iterator for the array. What am I doing wrong?
Solution 1:[1]
Different problems here:
- You cannot use
array::IntoIterator
because you do not have an array, you have a slice, which is quite different. It can be solved, for example, by using the propercore::slice::Iter
as in the example. - You are trying to return
T
but in reality you only give access to&T
, so returnItem
should be&T
- Your
into_slice
method uses a&mut
which is not necessary, you can reslice the storage for this implementation.
impl <'a, T:'a> IntoIterator for StackVec<'a, T> {
type Item = &'a T;
type IntoIter = core::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.storage[0..self.len].into_iter()
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |