И сразу ответы на вопросы:
▸ Почему такая странная сигнатура у f?
С приходом дженериков, необходимость итерации по кастомным структурам данных встала особенно остро - в особенности по тем, в которых невозможно или очень сложно зафиксировать текущее положение. В качестве примера - попробуйте придумать итератор который будет работать одновременно и для []string
и map[string]string
. Затем попробуйте придумать как добавить поддержку древовидной структуры данных. А затем добавьте в микс каналы. Когда дойдете до import "reflect"
можно смело останавливаться.
▸ Почему нельзя сделать интерфейс?
На самом деле нет большой разницы между func(yield func(T1, T2)bool) bool
и type Iterator interface { Iter(yield (V T, V2 T2) bool) bool }
. Более того, вариант с интерфейсом обсуждали, но решили отказаться от него, т.к. это будет противоречить принципам языка, где методы у типов не являются обязательным условием для полноценности этого самого типа. Кому интересно, можете погрузиться в дискуссии про дженерики - там это хорошо прописано. Кроме того, в текущем предложении это вызывает проблемы с взаимодействием с типом type MyInt int
у которого обьявлен метод Iter
.
▸ Как поиграться и попробовать на практике?
go install golang.org/dl/gotip@latest
gotip download 510541 # download and build CL 510541
gotip version # should say "(w/ rangefunc)"
gotip run foo.go
>>Click here to continue<<