
Итератор на Go
Итератор — это поведенческий паттерн, позволяющий последовательно обходить сложную коллекцию, без раскрытия деталей её реализации.
Благодаря Итератору, клиент может обходить разные коллекции одним и тем же способом, используя единый интерфейс итераторов.
Концептуальный пример
Суть паттерна Итератор – извлечь логику последовательного прохождения коллекции в отдельный объект под названием «итератор». Этот итератор предоставляет универсальные методы для последовательного прохождения коллекции независимо от ее типа.
collection.go: Коллекция
package main
type collection interface {
createIterator() iterator
}
userCollection.go: Конкретная коллекция
package main
type userCollection struct {
users []*user
}
func (u *userCollection) createIterator() iterator {
return &userIterator{
users: u.users,
}
}
iterator.go: Итератор
package main
type iterator interface {
hasNext() bool
getNext() *user
}
userIterator.go: Конкретный итератор
package main
type userIterator struct {
index int
users []*user
}
func (u *userIterator) hasNext() bool {
if u.index < len(u.users) {
return true
}
return false
}
func (u *userIterator) getNext() *user {
if u.hasNext() {
user := u.users[u.index]
u.index++
return user
}
return nil
}
user.go: Клиентский код
package main
type user struct {
name string
age int
}
main.go: Клиентский код
package main
import "fmt"
func main() {
user1 := &user{
name: "a",
age: 30,
}
user2 := &user{
name: "b",
age: 20,
}
userCollection := &userCollection{
users: []*user{user1, user2},
}
iterator := userCollection.createIterator()
for iterator.hasNext() {
user := iterator.getNext()
fmt.Printf("User is %+v\n", user)
}
}
output.txt: Результат выполнения
User is &{name:a age:30}
User is &{name:b age:20}
По материалам: Golang By Example