4 ms·
I would probably just do the following: type Iterator[T any] interface { HasNext() bool GetNext() T } And then use it like: for i
by Kamq 3y ago
I would probably just do the following:
type Iterator[T any] interface {
HasNext() bool
GetNext() T
}
And then use it like:
for i.HasNext() {
current := i.GetNext()
// do things here
}
It's an extra line, sure, but it's pretty obvious what's going on.
- pkolaczk 3y agoThis is the way how Java iterators work. And having worked with them for many years I must say - please don't go that route. Having separate hasNext/next methods is terrible for implementers of the iterator. The problem arises when you need to actually compute the next item to learn if it exists. So then your hasNext is actually effectful and needs to cache the result internally. There are so many ways to get it wrong, I've even seen some terrible implementations which required the caller to call hasNext or otherwise they would not advance the iterator. Iterator design is another area where sum types would help simplify things a lot. Just one method returning Some/None would be so much better.
- masklinn 3y ago> Iterator design is another area where sum types would help simplify things a lot. Just one method returning Some/None would be so much better. It would be better, but since go has MRV and zero values func Next() (hasNext bool, nextValue T) works fine, this is not Java or C# where you need to split the protocol into two separate operations.
- Kamq 3y agoSince we're talking about implementing it in usercode, as opposed to adding it to the language, we fortunately have the option to rework it (or have a couple completing implementations to see what works in practice). If you're looking for those particular features, I'd recommend adopting go's `, ok` idiom that appears in several places in the language. A type like: type Iterator[T any] interface { Next() (T, bool) } Lets you write code like this, if that's more to your liking: for current, ok := i.Next(); ok; current, ok = i.Next() { // do things here } Which, really seems like a more go-like way to do this in the language as well (ranging over a function then becomes syntactic sugar for the above).