チャネルとは
GoルーチンとGoルーチンの間でデータの受け渡しをするためのGo特有のデータ構造。
チャネルの型
チャネルの型はchan データ型のように書く。以下の例はint型のチャネルを作っている。
var ch chan int
チャネルの特性
チャネルの中に何かしらのデータを入れると、それを取り出してからでないと他のGoルーチンはチャネルに何のデータも入れることができない。またチャネルから何かデータを取り出そうとしたときに空だった場合、箱に何かが入るまでプログラムの実行は中断される。
←chan
とすると受信専用チャネルになる。
var ch1 <-chan int
chan←
とすると送信専用チャネルになる。
var ch2 chan<- int
特に指定しないと双方向のチャネルとなる。
チャネルのバッファ
チャネルはキューの性質を備えるデータ構造。キューは先入先出の性質があり、キューに先に入れられたデータは先に取得される。
バッファはこのキューを格納する領域のこと。チャネルでは生成時にバッファサイズを指定できる。
以下はバッファサイズ8のチャネル
ch := make(chan int, 8)
何も指定しないとバッファサイズは0になる。
ch := make(chan int)
試してみた
実際に以下のようなコードを書いてチャネルの動きを確認してみた。receiver()
は引数でチャネルを受け取り、i
にチャネルで受信したデータを格納し、出力する関数。
main()
ではチャネルに整数i
を送信する操作をi<10
になるまで繰り返している。
package main
import (
"fmt"
)
func receiver(ch <-chan int) {
for {
i := <-ch
fmt.Println(i)
}
}
func main() {
ch := make(chan int)
go receiver(ch)
i := 0
for i < 10 {
ch <- i
i++
}
}
結果
$ go run dogorutin.go
0
1
2
3
4
5
6
7
8
9
受信できている。