LoginSignup
109
78

More than 3 years have passed since last update.

Go言語でチャネルとselect

Last updated at Posted at 2015-10-15

Go言語でチャネルとselectを使う場合の挙動についてのメモ

受信

単純に書くと以下のようになる。

// ch は chan
v := <- ch

ところが、チャネルが close されている場合はゼロ値が受信される。

値を受信したのか close によってゼロ値になったのかを区別するには左辺の2つめの変数でbool値を受け取る。

v, ok := <- ch
if ok {
    fmt.Println(v)
} else {
    fmt.Println("closed")
}

この ok はチャネルから受信した場合は true 、そうでない場合は false が入る。

select

チャネルに値が入っていない場合、受信はブロックする。ブロックせずに処理を行いたい場合は select を使う。

select {
case v := <- ch:
    fmt.Println(v)
default:
    fmt.Println("no value")
}

ch に値が入っている場合は case v := <- ch ケースが実行される。ch に値が入っていない場合は default ケースが実行される。default ケースが実行された場合はチャネルからの値の受信は行われない。

この時もチャネルが close されているとブロックせず case v := <- ch が実行される。受信か close か区別したい場合は以下のようにする。

select {
case v, ok := <- ch:
    if ok {
        fmt.Println(v)
    } else {
        fmt.Println("closed")
    }
default:
    fmt.Println("no value")
}

送信

単純に書くと以下のようになる。

// ch は chan
ch <- v

select

チャネルに空きがない場合、送信はブロックする。ブロックせずに処理を行いたい場合は select を使う。

select {
case ch <- v:
    fmt.Println("sent")
default:
    fmt.Println("no capacity")
}

ch に空きがある場合は case ch <- v ケースが実行され "sent" 表示、空きがない場合は default ケースが実行され "no capacity" 表示となる。default ケースが実行された場合はチャネルへの値の送信は行われない。

なお close したチャネルに送信しようとすると panic: send on closed channel となる。

109
78
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
109
78