web-dev-qa-db-ja.com

構造体のGolangチャネル:関数に渡されたときに方向性を持たせることができますか?

チャネルを関数に渡すとき、チャネルがそのチャネルを使用できる方向を指定できることを私は知っています。例えば、

func MyFunc(ch chan<- string) {
    ch <- "Hello"
}

「ch」は、MyFuncが他の場所の受信者に文字列を送信するためにのみ使用でき、MyFuncはchからのメッセージをリッスンできません。

動的な数のチャネルをいくつかのゴルーチンに簡単に作成するために、チャネルを含む構造体を作成しました。

type ChanStruct struct {
    chMessages chan string
}

次に、構造体をインスタンス化します。

var slcChanStruct []ChanStruct
for a:= 0; a <=2; a++ {
    var tmpChanStruct ChanStruct
    tmpChanStruct.chMessages = make(chan string)
    slcChanStruct = append(slcChanStruct, tmpChanStruct)
}

これで、構造体のスライス全体に及ぶことで、チャネルを使用して個別に読み取り/書き込みできる3つの構造体ができました。しかし、私がそれらをゴルーチンに送るとき:

for a:=0; a <=2; a++{
    go SomeFunc(slcChanStruct[a])
}

...たとえば、GoroutineがChanStruct.chチャネルを使用してのみ送信できるように指定することで、少し安全性を追加する方法はありますか?

これを行った理由は、チャネルを持つ構造体を使用してプロセスの並列セット(プロセスの数はコマンドライン引数として渡される)に必要なチャネル数がわからない場合、作成できることを意味するためです。任意の数のゴルーチンに渡すことができ、それらにまたがることによって個別に直接アクセスできるスライス。以前は、複数のゴルーチンから個別に読み取りたい場合は、設定された数のチャネルを作成する必要がありました。個々のチャネルを使用する場合と同様に、プロセスが特定の方法でのみチャネルを使用できるように指定することで、これに安全性を追加したいと思います(個々のチャネルは、特定のゴルーチンに、他のゴルーチンがインターセプトせずに終了するように指示するようなことを実行できることを意味します)。構造体のチャネルを使用して関数に方向性を追加できない場合、これを行うためのより慣用的な方法はありますか?

4

特定の状況に応じて、いくつかの方法があります。

  • 構造体の代わりにチャネルを渡し、最初の例のようにチャネルパラメータを指向性にします
  • チャネルを直接公開するのではなく、書き込み用のstructメソッドを公開するだけです(チャネルから読み取るメソッドがない場合は、事実上方向性があります)
  • チャネル構造体メンバーを指向性にします。

例えば。

type myStruct struct {
    c chan <- bool
}
1
Adrian