Когда вы возвращаете ссылку из функции, ее время жизни должно быть привязано к чему-то другому. В противном случае компилятор не будет знать, как долго действительна ссылка (исключение составляет 'static
время жизни, которое длится на протяжении всей программы).
Поэтому нам нужна существующая ссылка наломтикиОдин из стандартных способов сделать это - привязать ссылку к самому итератору. Например,
struct Iter<'a> {
slice: &'a [u8; 100],
num: usize,
}
Тогда то, что у вас есть, работает почти дословно. (Я изменил имена типов и полей, чтобы они были немного более информативными).
impl<'a> Iterator for Iter<'a> {
type Item = &'a [u8];
fn next(&mut self) -> Option<Self::Item> {
if self.num >= 100 {
return None;
}
let res = &self.slice[10 * self.num..10 * (self.num + 1)];
self.num += 1;
Some(res)
}
}
Теперь у вас, вероятно, все еще есть фактический [u8; 100]
где-то, а не просто ссылка. Если вы все еще хотите работать с этим, вам понадобится отдельная структура, которая имеет метод для преобразования в A
. Например,
struct Data {
array: [u8; 100],
}
impl Data {
fn iter<'a>(&'a self) -> Iter<'a> {
Iter {
slice: &self.array,
num: 0,
}
}
}
Благодаря выбору на всю жизнь время жизни на iter
можно не указывать:
impl Data {
fn iter(&self) -> Iter {
Iter {
slice: &self.array,
num: 0,
}
}
}
(детская площадка)
Просто несколько заметок. Была одна ошибка компилятора с [0u8; 100]
. Возможно, это была опечатка для [u8; 100]
, но на всякий случай, вот почему мы не можем этого сделать. В полях для определения структуры указываются только типы. Там нет значений по умолчанию для полей или что-то подобное. Если вы пытаетесь использовать по умолчанию для структуры, рассмотрите возможность использования черты Default
.
Во-вторых, вы, вероятно, знаете об этом, но уже есть реализация итератора куска для срезов. Если slice
является срезом (или его можно принудительно преобразовать в срез - векторы и массивы являются простыми примерами), то slice.chunks(n)
является итератором для фрагментов этого среза длиной n
. Я привел пример этого в приведенном выше коде. Интересно, что эта реализация использует очень похожую идею: slice.chunks (n) возвращает новую структуру с параметром времени жизни и реализует Iterator
. Это почти точно так же, как наша Data::iter
.
Наконец, ваша реализация next
содержит ошибку, которая вызывает панику вне пределов при запуске. Посмотри, сможешь ли ты это заметить!