3 ms·
Hmm, can you provide some examples of how a context based iterator is slow? If you need raw performance and you are just doing some minimal operations on a sli
by whoisjohnkid 5y ago
Hmm, can you provide some examples of how a context based iterator is slow?
If you need raw performance and you are just doing some minimal operations on a slice then yeah you’d want to use a simple for loop instead.
I typically use this pattern in situations where you have a ton of data coming back where you want to avoid storing all of that data in memory.
- throwaway894345 5y agoThe problem with using channels is that these require multiple goroutines and locking for a problem that's inherently singlethreaded. Instead, you can define an iterator as a function that returns a function: func intSliceIter(ints []int) func() (int, bool) { i := 0 return func() (int, bool) { if i < len(ints) { ret := ints[i] i++ return ret, true } return 0, false } } iter := intSliceIter([]int{0, 1, 2, 3, 4}) for x, ok := iter(); ok; x, ok = iter() { fmt.Println(x) } Of course, there's not much benefit to a SliceIter; this is a contrived example, but you can apply this pattern in more complicated cases as well. Similarly, you can define an iterator as an interface (which is similar to bufio.Scanner and a few others in the standard library—a closure is an object is a closure): type IntIter interface { Next() (int, bool) } type IntSliceIter struct { Cursor int Ints []int } func (isi *IntSliceIter) Next() (int, bool) { if isi.Cursor < len(isi.Ints) { ret := isi.Ints[isi.Cursor] isi.Cursor++ return ret, true } return 0, false }