4 ms·
You can encapsulate iteration logic in Go. I do it in my libraries when warranted. The pattern is: v := NewIteratedValue() for v.Next() { item := v.I
by kjksf 7y ago
You can encapsulate iteration logic in Go.
I do it in my libraries when warranted.
The pattern is:
v := NewIteratedValue()
for v.Next() {
item := v.Item
// process item
}
if v.Err() != nil {
// process error
}
A variation of this pattern exists in standard library and third part libraries.
I know that you meant implementing some sort of iteration protocol natively supported by the language, so that you can write:
for v { ... }
vs:
for v.Next() { }
But you ended up making much stronger and untrue claim that one can't write re-usable iteration logic in Go.
- atombender 7y agoThat's an apples-to-oranges comparison because your iterator interface here isn't generic like Rust's. It isn't reusable. Your iterator has to be specific to a set of types — "v.Item" in your example is always of some specific type. Using an untyped interface{} would be worse than any alternative because every single use would have to use type switches and casting; you lose out of compile-type type safety. Because of this, even if you have a local iteration system, it isn't composable beyond your package and its types. Given this (simpler) interface: type Iterator interface { Next() (Foo, error) } ...then I can write a map function: func Map(it Iterator, mapper func(Foo) Foo)) Iterator ...but I cannot write a generic one that works with anything other than Foo. And if I need this: func MapFooToBar(it Iterator, mapper func(Foo) Bar)) Iterator ...then I have to write it just for that purpose. That's why there's no "iterator library" for Go, like there is with Rust.
- asdkhadsj 7y ago> But you ended up making much stronger and untrue claim that one can't write re-usable iteration logic in Go. Not at all. Are you telling me that `v.Next()` can be written in a reusable way for different data structures? Nonsense. `v.Next()` will have a single, bound return type. So at that point you're re-implementing iterators for anything you want to iterate on. Furthermore, lets say I want to `v.Next().Map()`. How can I write a Map function in a reusable way? The entirety of your iterator chain would have to be custom implemented for the one data structure you're using. Or you throw your entire type information away and use `interface{}`. With Go, your limit of reusability is hand writing the entire iterator implementation per type. Which is hardly reusable in my view. I touched on this when I mentioned creating separate functions for these patterns. That's all you're doing here - creating custom methods to make something look like, but not behave like an actual iterator. No Map support, no Filter, no .. anything. All you made was a loop, and a hand written one. I'm not trying to be overly negative here. However saying Go has an iterator pattern is imo strongly misleading.