はじめに
Goでタスクトレイに常駐させるようなツールを作りたい
↓
systrayが使えそう
↓
example/main.goを流し読み
go func() {
for {
select {
case <-mChange.ClickedCh:
// 略
case <-mChecked.ClickedCh:
// 略
case <-mEnabled.ClickedCh:
// 略
case <-mUrl.ClickedCh:
// 略
case <-mToggle.ClickedCh:
// 略
case <-mQuit.ClickedCh:
// 略
}
}
}()
↓
メニューの項目が増えるとselectのcaseも増える。
できればchannelのsliceをselectで待ちたい。
解決策
Stack Over Flowにちょいどいい回答がありました。
selectそのままではなく、reflect.Selectを利用することで解決できるとのこと。
参考:How to listen to N channels dynamic select statement
サンプル
package main
import (
"fmt"
"reflect"
)
func main() {
numChans := 5
var chans [] chan struct{}
for i := 0; i < numChans; i++ {
tmp := make(chan struct{})
chans = append(chans, tmp)
go DoFunc(tmp)
}
cases := make([]reflect.SelectCase, len(chans))
for i, ch := range chans {
cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
}
remaining := len(cases)
for remaining > 0 {
chosen, _, ok := reflect.Select(cases)
if !ok {
cases[chosen].Chan = reflect.ValueOf(nil)
remaining -= 1
continue
}
fmt.Println(chosen)
}
}
func DoFunc(c chan<-struct{}) {
c <- struct{}{}
close(c)
}
タスクトレイから選択できる各メニューのchannelとそれに対応した処理を保持しておき、
メニューが選択された際にその処理を流せば実現できそうです。