1. ホーム
  2. go

[解決済み] Nチャンネルを聴くには?(動的選択文)

2022-05-17 17:49:57

質問

2つのゴルーチンを実行する無限ループを開始するために、以下のコードを使用することができます。

msgを受信したら、新しいゴルーチンを開始し、永遠に続きます。

c1 := make(chan string)
c2 := make(chan string)

go DoStuff(c1, 5)
go DoStuff(c2, 2)

for ; true;  {
    select {
    case msg1 := <-c1:
        fmt.Println("received ", msg1)
        go DoStuff(c1, 1)
    case msg2 := <-c2:
        fmt.Println("received ", msg2)
        go DoStuff(c2, 9)
    }
}

今度はN個のゴルーチンに対して同じ動作をさせたいのですが、その場合select文はどうなるのでしょうか?

これは私が始めたコードビットですが、select文をどのようにコード化するのか混乱しています。

numChans := 2

//I keep the channels in this slice, and want to "loop" over them in the select statemnt
var chans = [] chan string{}

for i:=0;i<numChans;i++{
    tmp := make(chan string);
    chans = append(chans, tmp);
    go DoStuff(tmp, i + 1)

//How shall the select statment be coded for this case?  
for ; true;  {
    select {
    case msg1 := <-c1:
        fmt.Println("received ", msg1)
        go DoStuff(c1, 1)
    case msg2 := <-c2:
        fmt.Println("received ", msg2)
        go DoStuff(c2, 9)
    }
}

どのように解決するのですか?

を使って行うことができます。 Select 関数を使用します。 反映 パッケージを使用します。

func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool)

Selectはケースのリストで記述されたselect操作を実行します。Goのselect文と同様に Goのselect文のように、少なくとも1つのケースが実行可能になるまでブロックし 一様な擬似ランダム選択を行い、そのケースを実行します。 を実行します。選択されたケースのインデックスと、そのケースが受信操作であった場合、受信した値と 受信操作の場合は,受信した値と,その値が送信操作に対応するかどうかを示すブーリアン その値がチャネル上の送信に対応するかどうかを示すブーリアン値を返します。 というブール値を返します。)

の配列で渡します。 SelectCase 構造体の配列で、選択するチャンネル、操作の方向、送信操作の場合は送信する値を指定します。

つまり、次のようなことができるわけです。

cases := make([]reflect.SelectCase, len(chans))
for i, ch := range chans {
    cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
}
chosen, value, ok := reflect.Select(cases)
// ok will be true if the channel has not been closed.
ch := chans[chosen]
msg := value.String()

ここでは、より具体的な例で実験することができます。 http://play.golang.org/p/8zwvSk4kjx