有几个要监视的通道,它们的类型不同且不相关(因为我们只关心len和cap),但是golang编译器不接受以下代码,无论T是什么。
func monitorChan(ch chan T) {
for {
if len(ch) == cap(ch) {
log.Warn("log")
}
time.Sleep(chanMonitorInterval)
}
}
显示错误:
不能在参数中使用ch(类型chan [] byte)作为类型chan接口{} 来监视Chan。
如何修改此功能以在每个通道上写入一次监视器?
这是我的代码:
package main
import (
"fmt"
"time"
)
func monitorChan(ch chan interface{}) {
for {
if len(ch) == cap(ch) {
fmt.Println("log")
}
time.Sleep(1 * time.Second)
}
}
func main() {
ch := make(chan []byte, 100)
go monitorChan(ch)
// actual things below ...
}
答案 0 :(得分:3)
使用反射。例如,
package main
import (
"log"
"reflect"
"time"
)
func monitorChan(ch interface{}, intvl time.Duration) {
v := reflect.ValueOf(ch)
if v.Kind() != reflect.Chan {
return
}
c := v.Cap()
if c == 0 {
return
}
for {
if l := v.Len(); l == c {
log.Printf("log: len(%d) cap(%d)", l, c)
}
time.Sleep(intvl)
}
}
func main() {
log.Print("main")
c := make(chan []byte, 10)
var chanMonitorInterval = 1 * time.Second
go monitorChan(c, chanMonitorInterval)
log.Print("monitor")
time.Sleep(5 * chanMonitorInterval)
for len(c) != cap(c) {
c <- []byte{}
}
log.Print("len(c) == cap(c)")
time.Sleep(3 * chanMonitorInterval)
<-c
log.Print("len(c) < cap(c)")
time.Sleep(5 * chanMonitorInterval)
log.Print("main")
}
游乐场:https://play.golang.org/p/c5VhIIO0pik
输出:
2009/11/10 23:00:00 main
2009/11/10 23:00:00 monitor
2009/11/10 23:00:05 len(c) == cap(c)
2009/11/10 23:00:06 log: len(10) cap(10)
2009/11/10 23:00:07 log: len(10) cap(10)
2009/11/10 23:00:08 log: len(10) cap(10)
2009/11/10 23:00:08 len(c) < cap(c)
2009/11/10 23:00:13 main
参考文献:
答案 1 :(得分:-1)
创建一个interface{}
类型的通道并传递环绕interface{}
的所有类型,然后在接收端获取使用类型的断言。
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func monitorChan(ch chan interface{}) {
val := <-ch
fmt.Println(string(val.(interface{}).([]uint8)))
wg.Done()
}
func main() {
ch := make(chan interface{}, 100)
wg.Add(1)
ch <- []byte("hello")
go monitorChan(ch)
wg.Wait()
// actual things below ...
}
在Go Playground上工作的代码
已编辑:-您也可以在将频道包装在interface{}
package main
import (
"fmt"
"sync"
"reflect"
)
var wg sync.WaitGroup
func monitorChan(i interface{}) {
defer wg.Done()
v := reflect.ValueOf(i)
fmt.Printf("%s size: %d/%d\n", v.Kind(), v.Len(), v.Cap())
}
func main() {
ch := make(chan []byte, 100)
wg.Add(1)
go monitorChan(ch)
wg.Wait()
// actual things below ...
}