Ответ 1
Примечание по используемой версии Rust:, когда этот вопрос и ответ были написаны, черта
Iterator
использовала дженерики; он изменил использование связанных типов и теперь определяется таким образом:pub trait Iterator { type Item; fn next(&mut self) -> Option<Self::Item>; … }
И поэтому приведенная здесь некорректная реализация будет выглядеть следующим образом:
impl<'a> Iterator for Foo { type Item = &'a u8; fn next<'a>(&'a mut self) -> Option<&'a u8>; }
В практическом плане это ничего не влияет; просто
A
становитсяSelf::Item
.
Определение признака Iterator
таково:
pub trait Iterator<A> {
fn next(&mut self) -> Option<A>;
…
}
Примечание внимательно: fn next(&mut self) -> Option<A>
.
Вот что у вас есть:
impl<'a> Iterator<&'a u8> for Foo {
fn next<'a>(&'a mut self) -> Option<&'a u8>;
}
Примечание внимательно: fn next<'a>(&'a mut self) -> Option<&'a u8>
.
Здесь есть несколько проблем:
-
Вы ввели новый общий параметр
<'a>
, которого не должно быть. Для удобства и для того, чтобы подчеркнуть, что здесь произошло, я буду дублировать'a
, определенный в блоке impl и p'a
, определенном на методе ρ₁. Они не то же самое. -
Время жизни
&mut self
отличается от времени жизни. -
Время жизни возвращаемого типа отличается от черты: где
A
-&'ρ₀ u8
, тип возврата используется вместоA
&'ρ₁ u8
. Он ожидал конкретного времени жизни ρ₀, но вместо этого нашел время жизни ρ₁. (Я не уверен точно, что означает бит "связанный", поэтому я буду молчать, чтобы я не ошибся.)
Вот что это значит: вы не можете связать время жизни объекта, который вы перебираете, на &mut self
. Вместо этого он должен быть связан с чем-то в типе, для которого вы реализуете черту. Например, повторение элементов в срезе выполняется путем создания нового объекта итератора, подключенного к базовому фрагменту, impl<'a, T> Iterator<&'a T> for Items<'a, T>
. Выраженный иначе, то, как создаются итерационные черты, не является, если вы создаете ссылки, для того, чтобы вы возвращали что-то внутри self
, а скорее возвращали что-то внутри другого объекта, на который вы ссылаетесь.
Для вашего конкретного, предположительно простого примера, вы должны либо прекратить давать ссылки, либо изменить его так, чтобы ваш объект итератора не содержал данные, которые вы итерируете, пусть он просто содержит ссылку на него, например. &'a [T]
или даже что-то вроде Items<'a, T>
.