go / expert
Snippet
Dynamisches Kanal-Multiplexing über dynamische Laufzeit-Reflexions-Select-Fälle
Wenn die Anzahl der zu empfangenden Kanäle erst zur Laufzeit feststeht, reichen statische Select-Blöcke nicht aus. Dieser Code nutzt reflect.Select, um dynamische Select-Fälle programmatisch zu erstellen und eine flexible Fan-In-Aggregation über beliebig viele Kanäle zu ermöglichen.
snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package mainimport ("reflect")type MultiResult struct {Index intValue anyOk bool}func MultiplexChannels(chans []chan any) MultiResult {cases := make([]reflect.SelectCase, len(chans))for i, ch := range chans {cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv,Chan: reflect.ValueOf(ch),}}chosen, recv, ok := reflect.Select(cases)var val anyif recv.IsValid() {val = recv.Interface()}return MultiResult{Index: chosen, Value: val, Ok: ok}}
Erklärung
1
cases[i] = reflect.SelectCase{ Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch) }
Erstellt einen Reflexions-Select-Fall mit Empfangsmodus und dem zugrunde liegenden Channel-Value.
2
chosen, recv, ok := reflect.Select(cases)
Blockiert, bis einer der dynamisch vorbereiteten Kanäle einen Wert liefert oder schließt, und gibt den Index zurück.