![Iterator](/images/patterns/cards/iterator-mini.png?id=76c28bb48f997b36965983dd2b41f02e)
Iterator を Go で
Iterator は、 振る舞いに関するデザインパターンの一つで、 複雑なデータ構造の内部の詳細を公開することなく、 順次横断的に探索することを可能とします。
Iterator のおかげで、 クライアントは、 異なるコレクション上の要素の探索を、 単一のイテレーター・インターフェースを使用して同様の方法で行えます。
概念的な例
Iterator パターンの基本的な考え方は、 コレクションの反復ロジックをイテレーターと呼ばれる別のオブジェクトに抽出することです。 このイテレーターは、 型から独立した、 コレクション上の反復を行う一般的メソッドを提供します。
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}