【Go】channelとは

参考書を写経していたらchannelを使用していたのですが、いまいちイメージがつかなかったので、調べてみました。とりあえず、動作確認してみて、あーなるほどね。ぐらいを目指した記事です。

channelとは

goroutine間でデータの受け渡しをするデータ構造。そもそもgoroutineに関する勉強はあとに回しているので、一旦覚えることにします。一つ言えるのは、goroutineを使った処理、つまり非同期処理をしないのであれば特に使用しないということ

コード

func Channel() {
	ch := make(chan string, 2)

	go GoroutineTest(ch)
	go GoroutineTest2(ch)

	time.Sleep(1 * time.Second)

	fmt.Println(<-ch)
	fmt.Println(<-ch)

}

func GoroutineTest(ch chan string) {
	fmt.Println("Test1")
	ch <- "one"
}

func GoroutineTest2(ch chan string) {
	fmt.Println("Test2")
	ch <- "two"
}

出力結果①

Test2
Test1
two
one

出力結果②

Test1
Test2
one
two

イメージ図

f:id:c_taquna:20190628002521p:plain:w500

コードの確認

channelの生成

キャパシティ2でstring型のchannelを生成

ch := make(chan string, 2)

GoroutineTest, GoroutineTest2 を非同期で呼び出し

go GoroutineTest(ch)
go GoroutineTest2(ch)

ここで ch<- でチャネルに文字列を受信しています。goでの呼び出しは処理の順番が決まっていないので、"one"が先に出力される場合と"two"が先に出力される場合があります。

ちなみに、チャネルはキューのデータ構造です。

func GoroutineTest(ch chan string) {
	fmt.Println("Test1")
	ch <- "one"
}

func GoroutineTest2(ch chan string) {
	fmt.Println("Test2")
	ch <- "two"
}

<-ch は受信です。呼び出した回数分受信を行います。先程書いたようにキューなのでFIFOで表示されます。

fmt.Println(<-ch)
fmt.Println(<-ch)

とりあえずまとめ

main処理側でチャネルを生成し、呼び出した関数でチャネルに値を送信する。その後main処理に戻ってチャネルの内容を受信する。ってとこですかね。