Goroutinesの探求の記事で見たように、チャネルはGoroutines間の通信手段です。この記事では、channelsについてさらに詳しく探求していきます。
Channel とは?
- Goroutine は独立して動作し、それぞれ独自の処理を行います。しかし、Goroutine 間で 通信 が必要な場合があります。そこで チャネル が使用されます。
- チャネルは、データを格納したり データを取り出したり できるメモリ上のブロックのようなものと考えてください。
- デフォルトでは、
channelsはゴルーチン間のハンドシェイクのように動作します:- チャネルにデータを送信すると、ゴルーチンは別のゴルーチンが受信準備を整えるまで待機します
- 空のチャネルからデータを受信しようとすると、ゴルーチンは別のゴルーチンが何かを送信するまで待機します
- このブロッキング動作により、データの送受信が同期化されます。
- 通信はデフォルトで双方向です。つまり、同じチャネルから値を送受信できます。

チャネルはいつ使うべき? 🤔
channelsを深く学ぶ前に、実際に必要な場面を理解することが重要です。すべてのプログラムに並行処理が必要なわけではなく、channelsやgoroutineを追加するとコードが複雑になる可能性があります。
channelsを使用すべき場合
- 独立して並列実行可能なタスクがある場合(例:複数ファイルの処理)
- データを生成するプロデューサーと、異なる速度で処理するコンシューマーが存在する場合(例:リクエストを処理するWebサーバー)
- 結果を共有したり作業を調整する必要がある複数のワーカーがいる場合(例:ウェブクローラー)
- メインプログラムをブロックしたくない長時間の処理がある場合
ほとんどのプログラムはシンプルに始まります。並行処理は、パフォーマンス向上や複数のタスクを同時に処理するなど、明確な必要性が生じた段階で導入できます。
Channels の操作 ⚒️
チャネルの作成:
チャネルは make() 関数を使用して作成します。チャネルを作成する際には、チャネルの データ型 と 容量 を指定する必要があります。容量を指定しない場合、容量0のチャネルとなり、これは バッファなし チャネルと呼ばれます。
unbuffered := make(chan string) // バッファなしチャネル
buffered := make(chan int, 5) // 容量5のバッファ付きチャネル
チャネルへのデータ送信:
<- 演算子は、チャネルにデータを送信するために使用されます。これは「このデータをチャネルに送信する」という意味です。
ch <- "データ"
チャネルからのデータ受信:
<- 演算子は、チャネルからデータを受信する際にも使用されますが、方向が逆になります。これは「チャネルからデータを受信する」ことを意味します。
data := <-ch
送信と受信の両方が、デフォルトではブロッキング操作です。
チャネルが閉じられているか確認する:
channelからデータを受信している間、チャネルが閉じられているかどうかを示すための2つ目のブール値『ok』も返します。
data, ok := <-ch
if !ok {
fmt.Println("チャネルは閉じられています")
}
チャネルの閉じ方:
close()関数を使用して行います。チャネルを閉じることは、それ以上データが送信されないことを示します。メモリリークを回避し、受信側にデータ送信が終了したことを通知するため、チャネルを閉じることは非常に重要です。
close(ch)