Go 反射。选择功能是需要的为什么?我假设这是因为通道必须是反射值?
在什么情况下会反映。选择需要的 我找到了一些例子,但Select的使用似乎是人为的 有没有任何例子表明reflect.Select比普通Select更重要?MongoDB的同事们发了一封邮件。显然,这段代码在他们的Go 反射。选择功能是需要的为什么?我假设这是因为通道必须是反射值?,go,Go,在什么情况下会反映。选择需要的 我找到了一些例子,但Select的使用似乎是人为的 有没有任何例子表明reflect.Select比普通Select更重要?MongoDB的同事们发了一封邮件。显然,这段代码在他们的mongodump实用程序中正在生产中使用 使用reflect.Select的特定代码如下所示(摘自文章): 我认为他们使用的原因反映了。选择而不是直接的选择: goroutine的数量(因此通道的数量)在运行时确定(使用-j标志)。事实上,它似乎随着append而动态变化。(归功于
mongodump
实用程序中正在生产中使用
使用reflect.Select的特定代码如下所示(摘自文章):
我认为他们使用的原因反映了。选择而不是直接的选择:
- goroutine的数量(因此通道的数量)在运行时确定(使用
-j
标志)。事实上,它似乎随着append
而动态变化。(归功于@cnicutar的评论)
- 通道的类型在运行时确定。这使得他们的
muxInput.collection
类型可以是它想要的任何类型。(归功于@JimB的评论)
如果您的频道是固定的,您可以使用select观看它们;
但是,如果您的频道未固定,并且您希望观看它们,则可以使用reflect.Select
这里有一些代码片段
var (
events []reflect.SelectCase
err error
lenHdr = 3 // zk conn event chan, shutdown chan, children refresh chan
lenCW = len(z.ChildWatches) // a channel slice:chan ChildWatche
lenDW = len(z.DataWatches) //a channel slice:chan DataWatche
lenEN = len(z.EphemeralNodes) //a channel slice: chan EphemeralNode
)
events = make([]reflect.SelectCase, lenHdr+lenCW+lenDW+lenEN)
events[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(FreshChanConEvent())} // kick off the event loop
events[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(z.shutdownChan)}
events[2] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(z.refreshChildChan)}
for i, _ := range z.ChildWatches {
events[lenHdr+i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.Zero(reflect.TypeOf((chan zk.Event)(nil)))}
}
for i, _ := range z.DataWatches {
events[lenHdr+lenCW+i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.Zero(reflect.TypeOf((chan zk.Event)(nil)))}
}
for i, info := range z.EphemeralNodes {
events[lenHdr+lenCW+lenDW+i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(info.Ch)}
}
for {
chosen, value, ok := reflect.Select(events)
if chosen == xxxxx {...}
此代码正在监视通道数组(z.childwatchs、z.datawatchs、z.EphemeralNodes)一个示例是在动态数量的通道上进行选择,或者仅选择特定类型未知的通道。
var (
events []reflect.SelectCase
err error
lenHdr = 3 // zk conn event chan, shutdown chan, children refresh chan
lenCW = len(z.ChildWatches) // a channel slice:chan ChildWatche
lenDW = len(z.DataWatches) //a channel slice:chan DataWatche
lenEN = len(z.EphemeralNodes) //a channel slice: chan EphemeralNode
)
events = make([]reflect.SelectCase, lenHdr+lenCW+lenDW+lenEN)
events[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(FreshChanConEvent())} // kick off the event loop
events[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(z.shutdownChan)}
events[2] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(z.refreshChildChan)}
for i, _ := range z.ChildWatches {
events[lenHdr+i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.Zero(reflect.TypeOf((chan zk.Event)(nil)))}
}
for i, _ := range z.DataWatches {
events[lenHdr+lenCW+i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.Zero(reflect.TypeOf((chan zk.Event)(nil)))}
}
for i, info := range z.EphemeralNodes {
events[lenHdr+lenCW+lenDW+i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(info.Ch)}
}
for {
chosen, value, ok := reflect.Select(events)
if chosen == xxxxx {...}