
Iterator w języku Go
Iterator to behawioralny wzorzec projektowy pozwalający sekwencyjnie przechodzić od elementu do elementu jakiegoś zbioru bez konieczności eksponowania jego formy.
Dzięki Iteratorowi klienci mogą przeglądać kolejne elementy różnych kolekcji w podobny sposób, za pośrednictwem jednego interfejsu.
Przykład koncepcyjny
Główną ideą kryjącą się za wzorcem Iterator jest ekstrakcja logiki przechodzenia przez kolejne elementy jakiejś kolekcji do osobnego obiektu zwanego iteratorem. Iterator udostępnia generyczną metodę służącą przechodzeniu przez elementy kolekcji obiektów niezależnie od ich typu.
collection.go: Kolekcja
package main type Collection interface { createIterator() Iterator }
userCollection.go: Konkretna kolekcja
package main type UserCollection struct { users []*User } func (u *UserCollection) createIterator() Iterator { return &UserIterator{ users: u.users, } }
iterator.go: Iterator
package main type Iterator interface { hasNext() bool getNext() *User }
userIterator.go: Konkretny iterator
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: Kod klienta
package main type User struct { name string age int }
main.go: Kod klienta
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: Wynik działania
User is &{name:a age:30} User is &{name:b age:20}
Na podstawie: Golang By Example