2 min read
Custom iterators
Until recently, custom iterators were probably the most common way to iterate over a list of elements that might trigger an error. Several examples exist in the standard library. Perhaps the most well known would be the sql.Rows type, which provides (among others), the following methods: Next() bool — Advances to the next item Scan(...any) error — Processes the current item Err() error — Reports an iteration error Close() error — Closes iterator, possibly before the last item has been processed These four methods are pretty standard, in any custom iterator implementation, though Scan() will typically be replaced with an implementation-specific method to process the current result, and in some cases Err() and Close() may be combined.
3 min read
Iterating over channels
For this discussion of iterators, let’s establish a baseline example. It’s made up, but realistic and common: A database method that returns all user orders. We’ll be experimenting with different function signatures, but in general, this is what we can imagine it will look like: func (DB) Orders(ctx context.Context, userID string) ([]*Order, error) And we would consume it with code something like this: orders, err := db.Orders(ctx, userID) if err !
2 min read
Iterator patterns
I’m going to change gears from the previous discussion about goroutines, to different ways of iterating. This can closely relate to goroutines, so we’ll bounce back and forth a bit, I suspect. Meanwhile, if you have any questions specifically about goroutines that I didn’t cover, send me an email. I’ll be happy to fill in those gaps! First off, before really diving into iterator patterns, let’s talk about why we might want iterators.