3

I have a indexable type that I want to iterate over. It consists of some metadata and an array. I need to first iterate over the bytes of the metadata and then to that of the array. From what I understand, the iterator cannot have any storage local to the trait implementation. I think this is very disorganized, and I don't want my data types to be muddled by the need to satisfy extraneous influence.

impl Iterator for IndexableData {
  type Item = u8
  let index : isize = 0;
  fn next(& mut self) -> Option<Item> {
     if self.index > self.len() { None }
     if self.index > size_of::<Metadata> {
       Some (self.data[index - size_of::<Metadata>])
     } 
     Some (self.metadata[index])
  }
}

This is what I think the implementation should look like. The index variable belongs in the iterator trait. Not my IndexableData type. How can I achieve this?

4
  • Your question is very similar to this one: stackoverflow.com/questions/30218886/…. Commented Dec 30, 2015 at 14:59
  • Ah I didn't know about that question. I didn't find it when I was searching for what I was thinking of. Commented Dec 30, 2015 at 15:05
  • You should have known the solution to find that question :) Commented Dec 30, 2015 at 15:14
  • Rust's lifetime language is poorly documented and type parameterization language is wonky. On my end, I have all this impl<this + that + and + the + other> Commented Dec 30, 2015 at 15:17

1 Answer 1

7

The Iterator should be a separate struct that has a reference to the collection plus any other data it may need (such as this index). The collection object itself should not be an iterator. That would not only require misplaced additional metadata in the collection, it would prevent you from having multiple independent iterators over the collection.

Sign up to request clarification or add additional context in comments.

4 Comments

This ends up making a lot of interoperation with other traits very wonky. What I mean by that is that, the data of interest is what the programmer starts out with and wants to focus on, but in the process of conforming to the type checker, they end up making all these ancillary structs that hide behind the scenes of what is otherwise an innocuous set of methods that make up the public interface. Programmers aren't interested in making all those other structs because that's fundamentally just noise forced by the language.
In addition, that noise has the potential to complicate other tasks when interoperation between traits behind the scenes is required.
@AdamMiller This is not pointless boilerplate enforced to ruin your day. Iterators (in the sense used here) are separate from collections in every language I am aware of (though some make it a bit easier to define one-off iterators, like e.g. generators in Python). It is logically necessary because, as I said, you want the ability to have multiple iterator over a collection and not carry the baggage of an iterator when that is not required. [For lack of examples I cannot address your points about "other traits".]
I don't disagree - you agree with only half of what I'm addressing. First, it's correct to isolate other data types from the public interfaces and only reveal the consumer api that is as minimalist as possible. But the problem that I'm identifying is that having so many types to wrangle is turning it into a rodeo. To be honest, for lots of interfaces, I don't want the type to ever be used again. It seemed to make sense to me to have trait local private fields, where the compiler would use to auto-derive a struct with. Seems less cumbersome to me, but admittedly only sometimes more intuitive.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.