Go学習のチャンネルまとめ
ChannelはGoのコアタイプで、パイプと見なし、コアユニットを並列に接続することでデータを送信または受信して通信することができます.
を選択します。
双方向:chan T 一方向送信のみ:chan
一方向のみ:
一方的なchannelは、
を選択します。
Tは任意の種類を表す
一方的なchannelは、
make(chan , chan
を するだけでなく、 のように することができます.func main() {
channel := make(chan int, 10)
convert(channel)
}
func convert(channel chan
convert , channel
chanであれば、 も もできるのに、なぜ chanが するのか. の の1つは、 の です. えば、 システムでは、ページの をキャプチャし、プロセスbに するプロセスaがあります.プロセスaは chan
で です.
Blocking
デフォルトでは、 chanまたは chanは、 が できるまでブロックされます.この は、 されたロックや を することなくgororutineで するために することができる.
の ではx, y := channel 。
func bufferChannel() {
channel := make(chan int)
i := 0
go func(i int) {
fmt.Printf("start goroutine %d
", i)①
channel
は の りです.start goroutine 0
sleep 2 second
got 0
send 0 to channel
go func
が①まで された は②を し けるのではなく、③の が するのを ってから②を していることがわかる.
もし、 はここでブロックしたくないならば、 は データをchannel goroutine
の に いて、 が ができたら、channel
の で でどのように するかを って、ここでもう つの buffered channelに しています.
buffered channel
プログラムを しますfunc bufferChannel() {
channel := make(chan int, 1) //
i := 0
go func(i int) {
fmt.Printf("start goroutine %d
", i)①
channel
start goroutine 0
send 0 to channel
sleep 2 second
got 0
channel
が①を した に②を していることを し、③の が わるのを っていない.これがbuffered channelの である.
makeの 、 の2つのパラメータ、つまりchanのバッファサイズを するだけでいいです.
の から かるように, は3の ,すなわちgo func
を いてきた.for {
value
もっと な はありますか?
for … range
それとも のプログラムですか、for...rangeを って します.func bufferChannel() {
channel := make(chan int, 1)
i := 0
go func(i int) {
fmt.Printf("start goroutine %d
", i)
channel
これで chan , goroutine chan ,
のデータを ることができますが、 たちは に します.ああ、このプログラムはどうして まらないのですか.channel
で された はChannelで された であり、channelが じられるまで されるので、range channel
でデータを した 、goroutine
を じてみましょう. は、channel
は われません.func bufferChannel() {
channel := make(chan int, 1)
i := 0
go func(i int) {
fmt.Printf("start goroutine %d
", i)
channel
これにより、プログラム が に するので、time.Sleep(2 * time.Second)
を するときは が です.range
が じなければ、channel
はずっとここに まっています.
select
の で うのはずっと1つのrange
だけの 、 はどのようにするべきで、2つのchannel
あるいはそれ のchannel
が って、 はどのようにするべきで、ここでgoの の のchannel
を して、 のプログラムを にとりますfunc example() {
tick := time.Tick(time.Second)
after := time.After(3 * time.Second)
for {
select {
case
select
はgoのtimeパケットが するタイマの であり、time.Tick
を し、 された でchannelにデータを し、channel
は このchannelにデータを する.time.Tick(time.Second)
はgoのtimeパケットが するタイマの であり、time.After
を し、 された にchannelにデータを し、channel
は3 s にこのchannelにデータを する.
come into default
come into default
tick 1 second
come into default
come into default
tick 1 second
come into default
come into default
tick 1 second
after 3 second
time.After(3 * time.Second)
は、ブロックされていないselect
を し、 channel
の を することによって、case
のブロックによる の ブロックを することができることが かる.
たちは さな を けて、 に じたchannel
をchannel
の に れて してみましょう.func example() {
tick := time.Tick(time.Second)
after := time.After(3 * time.Second)
channel := make(chan int, 1)
go func() {
channel
.
.
.
.
got 0
got 0
got 0
got 0
got 0
after 3 second
まさに の で、 いにも3 sを して に して、それではcaseの 、このchannelが したかどうかを することができますか?func example() {
tick := time.Tick(time.Second)
after := time.After(3 * time.Second)
channel := make(chan int, 1)
go func() {
channel
come into default
got 1
channel is closed
tick 1 second
channel is closed
channel is closed
after 3 second
よりselect
じるかどうか、okはtrueで、channelが であることを して、さもなくば、channelは じます