チャネルから送られてくるデータは、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