🌀

Golangでのイテレータの使い方

2024/11/22に公開

Goでは、標準ライブラリで直接的なイテレータ構造を提供していないため、開発者が必要に応じてイテレータを実装する方法を知っておくと便利です。ここでは、簡単なイテレータの実装方法とGo 1.23のiterパッケージを利用した反復処理について紹介します。

なぜイテレータが便利なのか?

イテレータはコレクションやデータのシーケンスを扱う際に役立つ仕組みです。イテレータを使用すると、データを逐次的に取得することができるため、メモリ効率の向上やコードのシンプル化が図れます。

1. 基本的なイテレータの実装

まずは、Goで基本的なイテレータを実装する方法を見てみましょう。たとえば、整数のシーケンスを生成するイテレータを作成するには次のようにします。

package main

import "fmt"

// intIterator は整数を逐次返す関数
func intIterator(max int) func() (int, bool) {
	cur := 0
	return func() (int, bool) {
		if max <= cur {
			return 0, false // 終了
		}
		v := cur
		cur++
		return v, true
	}
}

func main() {
	nextInt := intIterator(5)
	for {
		v, ok := nextInt()
		if !ok {
			break
		}
		fmt.Println(v) // 0, 1, 2, 3, 4 が出力される
	}
}

このコードでは、intIterator関数がイテレータを返します。このイテレータは毎回1つの整数を返し、指定された上限まで進むと終了します。

2. Go 1.23のiterパッケージを使ったイテレータ

Go 1.23では、新たにiterパッケージが追加され、より便利なイテレータを提供しています。iterパッケージでは、シーケンスやキーと値のペアを扱うための機能が強化されており、カスタムのイテレータを作成しやすくなっています。

Seqを使ったシーケンス生成

Seq型は、データシーケンスを扱うための関数型で、yield関数を利用してデータを逐次返します。以下は、Seqを使って0から4までの整数を出力する例です。

package main

import (
	"fmt"
	"iter"
)

func main() {
	// 0から4までの整数シーケンスを生成
	seq := func(yield func(int) bool) {
		for i := range 5 {
			if !yield(i) {
				break
			}
		}
	}

	next, stop := iter.Pull(seq)
	defer stop()

	for {
		v, ok := next()
		if !ok {
			break
		}
		fmt.Println(v) // 0, 1, 2, 3, 4 が出力される
	}
}

この例では、Pull関数を使ってseqの各要素を取得しています。defer stop()によってイテレータの停止を確実に行い、リソース管理をシンプルにしています。

キーと値のシーケンス

Seq2は、キーと値のペアを持つシーケンスです。以下の例では、文字列とその長さのペアを生成するイテレータを作成しています。

package main

import (
	"fmt"
	"iter"
)

func main() {
	seq2 := func(yield func(string, int) bool) {
		items := map[string]int{"apple": 5, "banana": 6, "cherry": 6}
		for k, v := range items {
			if !yield(k, v) {
				break
			}
		}
	}

	next, stop := iter.Pull2(seq2)
	defer stop()

	for {
		k, v, ok := next()
		if !ok {
			break
		}
		fmt.Printf("%s: %d\n", k, v) // apple, banana, cherry が出力される
	}
}

このコードでは、mapのキーと値を逐次的に取得するイテレータを作成しています。iter.Pull2関数によってキーと値のペアを簡単に取得できます。

まとめ

Golangのイテレータはシンプルな反復処理を行いたい場合に役立ちます。Go 1.23で導入されたiterパッケージは、カスタムイテレータの作成をサポートし、より効率的で柔軟な反復処理を実現します。

イテレータの基本的な使用方法とiterパッケージの活用法を理解することで、Goでのデータ処理がより直感的かつ効率的になるでしょう。ぜひ実際に試してみてください!

Discussion