Go 言語では、select は非常に便利な言語構造です。複数のチャネルでデータの受信を待つことができます。いずれかのチャネルに受信するデータがあると、対応する操作がすぐに実行されます。ただし、Go 言語では select 文が使用できない場合があるので、以下でその状況を分析してみましょう。
最初に理解する必要があるのは、Go 言語でチャネルを宣言するときに、チャネルの型を指定する必要があるということです。チャネル、およびタイプが選択できる場合にのみ、比較、コピー、閉じるときにのみ使用できます。たとえば、以下に定義されているチャネル:
c1 := make(chan int) c2 := make(chan bool)
int 型と bool 型は比較可能な基本型であるため、これらはすべて選択できます。
ただし、構造体型のチャネルを定義する場合、select を直接使用することはできません。例:
type MyStruct struct { x int y string } c := make(chan MyStruct)
select が使用できない理由は、MyStruct 型を比較できないためです。チャネルタイプが MyStruct のチャネルの Use select では使用できません。
select には特殊なケース、デフォルト ステートメントがあり、すべてのケースをすぐに実行できない場合に実行されます。 select でデフォルト ステートメントを使用すると、いずれの場合でも受信するデータがあるときにデフォルト ステートメントも実行されます。
ただし、default ステートメントを使用する場合は、これまで考慮されていない状況も含め、選択で起こり得るあらゆる状況を考慮する必要があります。あらゆる状況を考慮しない場合、デフォルトを使用することはできません。そうしないと、潜在的なバグが発生する可能性があります。たとえば、次のコードは次のとおりです。
select { case msg1 := <-c1: fmt.Println("received", msg1) case msg2 := <-c2: fmt.Println("received", msg2) default: fmt.Println("nothing received") // 未考虑到其他情况的default语句 }
この例では、一部のデータが無視されたり、誤って処理されたりする可能性がある他のすべての状況は考慮されていません。したがって、default ステートメントを使用する場合は、考えられるすべての状況を考慮する必要があります。
デフォルトのステートメントに加えて、Go 言語での同期通信、つまりチャネルの状況もあります。バッファがいっぱいである、またはバッファがいっぱいの場合、データを書き込むことができず、他のゴルーチンがデータを受信するのを待つ必要があります。この場合、セレクトは使用できません。
たとえば、次のコード:
c := make(chan int, 1) c <- 1 c <- 2 // 缓冲区已满,此处会堵塞
この例では、バッファを持つチャネルを定義し、バッファ サイズは 1 です。最初にデータ 1 をチャネルに書き込み、次にデータ 2 をチャネルに書き込みますが、この時点でバッファがいっぱいであるため、この操作はブロックされます。 select でこのチャネルからデータを受信しようとすると、バッファーがいっぱいであるため、この操作もブロックされ、他の操作は実行できません。
したがって、select を使用する場合は、デッドロック状況を回避し、チャネルの読み取りおよび書き込み操作が独立して実行できるようにする必要があります。
つまり、Go 言語では select を正しく使用することが非常に重要であり、プログラミング エラーやデッドロックなどの問題を回避するには、あらゆる状況を考慮する必要があります。同時に、時間とリソースの無駄を引き起こす不適切な状況で select を使用することを避けるために、いくつかの特殊な状況を認識する必要もあります。
以上がGolangはselectを使用できませんの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。