select
文 - ゴルーチンの制御
Go言語は並行処理を強力にサポートしており、そのための主要なツールとしてゴルーチン(軽量スレッド)とチャネル(ゴルーチン間での通信メカニズム)があります。select
文は、複数のチャネル操作(送信や受信)の中から、実行可能なものを選択するための制御構造です。
基本的な使い方
select
文は、以下のような形式で使用します:
select {
case msg1 := <-ch1:
fmt.Println("Received", msg1)
case ch2 <- 2:
fmt.Println("Sent 2 to ch2")
case msg3, ok := <-ch3:
if ok {
fmt.Println("Received", msg3)
} else {
fmt.Println("ch3 is closed")
}
default:
fmt.Println("No communication")
}
上記の例で、以下のことが起こります:
-
msg1 := <-ch1
:ch1
からの受信を試みます。 -
ch2 <- 2
:ch2
への送信を試みます。 -
msg3, ok := <-ch3
:ch3
からの受信を試み、チャネルが閉じられている場合にはok
がfalse
になります。 -
default
: 他のcaseが実行可能でない場合に実行されます。
重要なポイント
-
非ブロッキング:
select
文は、実行可能なcaseがない場合、即座にdefault
ケースを実行します。default
がない場合、実行可能なcaseが現れるまでブロックされます。 -
複数のcaseが実行可能な場合: もし複数のcaseが同時に実行可能だった場合、
select
はランダムにその中の1つを選択して実行します。 -
タイムアウトの実装:
select
文は、特定のタイムアウトを持つ操作のために頻繁に使用されます。これは、time.After
関数と組み合わせることで、操作が一定時間内に完了しない場合のタイムアウトを実装するのに便利です。
例:
select {
case msg := <-ch:
fmt.Println("Received", msg)
case <-time.After(5 * time.Second):
fmt.Println("Timeout")
}
この例では、ch
からのメッセージを待つ間に5秒経過すると、"Timeout"というメッセージが出力されます。
まとめ
select
文は、ゴルーチンとチャネルを使用するGoプログラムにおいて、複数のチャネル操作の中から1つを選択するための強力なツールです。これを使うことで、非同期の通信やタイムアウトの実装が容易になります。