本文へスキップ
BecomeCoder

Goコース · 第6章 並行処理 · レッスン22

channel ― goroutine 間で値を受け渡す

ブラウザで完結

導入

別々に走る goroutine の間で、安全に値をやり取りする通り道が channel(チャネル) です。「メモリを共有して通信するな、通信してメモリを共有せよ」が Go の合言葉です。

説明

package main

import "fmt"

func main() {
    ch := make(chan string) // string を運ぶチャネルを作る

    go func() {
        ch <- "計算おわり" // チャネルに値を送る
    }()

    msg := <-ch // チャネルから値を受け取る(届くまで待つ)
    fmt.Println(msg)
}
  • make(chan string)string を受け渡すチャネルを作ります。
  • ch <- "..." … チャネルに値を 送る(矢印がチャネルへ向く)。
  • <-ch … チャネルから値を 受け取る(矢印がチャネルから出る)。
  • 受け取り側は、値が届くまで自動的に待ちます。この「待ち合わせ」が同期の役割を果たします。

前レッスンの time.Sleep で待つ代わりに、チャネルの受信で「処理が終わるまで待つ」を正確に表現できます。

やってみよう

go func() { ch <- "..." }() は、その場で無名関数を goroutine として起動する書き方です。msg := <-ch が「値が届くまで待つ」おかげで、Sleep なしでも結果を取りこぼしません。

実際に動かしてみよう

下のエディタにGoを書いて「実行」を押すと、学習用シミュレータが fmt の出力を表示します(本物のGoコンパイラではなく、教材の範囲を再現した軽量エンジンです)。スライス・マップ・構造体・インターフェース・goroutine/channel なども動きます。本文の例を書き換えて動かしてみましょう(並行処理の実行順は決定的に再現しているため、本物のインターリーブとは異なる場合があります)。

Go — ブラウザ内で実行(学習用シミュレータ)

Goの教材サブセットを動かす学習用シミュレータを読み込みます(本物のGoコンパイラではなく、動きを再現した軽量な自作エンジンです)。
スクロールして表示された時点でも自動で読み込まれます。