チャネルから送られてくるデータは、for
ループの range
で受けることもできる。
for v := チャネル { 処理 }
チャネルの場合、スライスやマップと違って返り値は多値ではない。あと、チャネルにデータを送る側では、送信が終わったらチャネルを close
する必要がある。
次の例は、二分木にチャネルを使ってデータを送信する each
関数を追加したものだ。
package main import ( "fmt" ) type Item interface { Eq(Item) bool Less(Item) bool } type Node struct { item Item left, right *Node } func newNode(x Item) *Node { p := new(Node) p.item = x return p } func insertNode(node *Node, x Item) *Node { switch { case node == nil: return newNode(x) case x.Eq(node.item): return node case x.Less(node.item): node.left = insertNode(node.left, x) default: node.right = insertNode(node.right, x) } return node } func foreachNode(f func(Item), node *Node) { if node != nil { foreachNode(f, node.left) f(node.item) foreachNode(f, node.right) } } type Tree struct { root *Node } func newTree() *Tree { return new(Tree) } func (t *Tree) insertTree(x Item) { t.root = insertNode(t.root, x) } func (t *Tree) foreachTree(f func(Item)) { foreachNode(f, t.root) } func (t *Tree) each() chan Item { ch := make(chan Item) go func() { t.foreachTree(func(x Item) { ch <- x }) close(ch) }() return ch } type Int int func (n Int) Eq(m Item) bool { return n == m.(Int) } func (n Int) Less(m Item) bool { return n < m.(Int) } func main() { a := newTree() b := []int { 5,6,4,3,7,8,2,1,9,0 } for _, x := range b { a.insertTree(Int(x)) } for x := range a.each() { fmt.Println(x) } }
for
ループの range
には二分木の each
関数を呼び出していて、その each
関数では、データを一つずつチャネルに送信し、最後にチャネルを close
している。
実行結果はこう:
^o^ > go run go_range.go 0 1 2 3 4 5 6 7 8 9