2016-12-22 4 views
0

チャネルから値を読み取るさまざまな方法が異なる振る舞いになるのはなぜか不思議です。提供されたコード:チャネルを読み取るための違いの方法

mychan := make(chan int) 

go func() { 
    i := 0 
    for { 
     mychan <- i 
     <-time.After(time.Second * 1) 
     i++ 
    } 
}() 

ゴルーチンmychanチャネルに無限整数のシーケンスを「ストリーム」。あなたはそのよう<-mychanで直接読み込む場合は、このコードの後、:予想通り

fmt.Println(<-mychan) 

これは、「0」を出力します。繰り返し続けている場合は、読み取りを続けます。

fmt.Println(<-mychan) // 1 
fmt.Println(<-mychan) // 2 
//... 

ただし、ルーピングメカニズムを使用すると、無限にブロックされます。

for i := range mychan { 
    fmt.Println(i) 
} 

つまり、このメカニズムはクローズドチャネルからのみ読み取ることができます。 しかし、select方法で、事はwierder取得します。

for i:=0; i<=10;i++ { 
    select { 
    case <-mychan: 
     fmt.Println(<-mychan) 
    } 
} 

は、今では同じように、交互に印刷さ1、3、5、9、... selectmychanや他のいくつかの不可視のチャンネルを切り替えたかのように、すべての2S。別のcase(しゃれが意図していない)ケースを作るの追加:誰も私を説明し、啓発することができれば、あなたのいくつかに思えるそれはよいとして

for i:=0; i<=10;i++ { 
    select { 
    case <-time.After(1 * time.Second): 
     fmt.Println("foo") 
    case <-mychan: 
     fmt.Println(<-mychan) 
    } 
} 

// now prints 1, foo, 3, foo, 5, foo, ... every 1s 

として、些細な質問を、私は感謝します。

+3

注意してこの問題を解決することができます。それは私の1、3、5、...を参照してください。あなたは、ケースiのmyhcan:fmt.Println(i)を希望するかもしれません。 – Volker

+0

すべてのチャンネルの受信操作は同じです。閉じたチャネルの状態を表示)。あなたが持っている動作の唯一の違いは、select文で受け取った値を1つおきに破棄することです。 – JimB

+0

https://play.golang.org/p/CEMKqJF3ya < - このコードスニペットは、範囲キーワードがオープンチャンネルで動作することを「証明」しています。なぜ私のプログラムがハングアップするのかはかなり興味があります。それは何とか閉じられないことを知っていますか? –

答えて

4

for i := range mychan { 
    fmt.Println(i) 
} 

から行動は、私はプログラムが無限毎秒つの値を出力ローカルコードを実行したときgo playground上の例を実行した結果と思われます。コードが永遠に実行されるかどうかを調べるために、サーバー上で使用しているコード解析ツールがあるとすばらしいことです。

Volkerが指摘しているように、2番目の例では、print文ごとにチャネルを2回読み込んでいます。 ( - mychan <) `**回** mychanから読み込み、最初の結果を破棄しfmt.Println:あなたはあなたの第二の符号`ケース<-mychanこと

for i:=0; i<=10;i++ { 
    select { 
    case <-time.After(1 * time.Second): 
     fmt.Println("foo") 
    case x, open := <-mychan: 
     if !open { return } 
     fmt.Println(x) 
    } 
} 
+1

よく見えます。ただし、最初のケースを省略するか、最初の印刷後に "foo"のみを印刷します。また、2番目のケースがありません ':= ' – PieOhPah

+0

Fooが私のためにプリントアウトしているようですか?私は理解しているか分からない(割り当て修正のおかげで) –

関連する問題