reflect.Select 函数是需要为什么?我认为这是因为通道必须是反射值?

在什么情况下会需要reflect.Select

我找到了例子,但 Select 的使用似乎是做作的。

任何示例,其中 reflect.Select 比正常选择是必要的?


UYOU
浏览 245回答 2
2回答

侃侃无极

最近有一篇来自 MongoDB 的人的文章。显然,此代码在其实用mongodump程序中用于生产。使用的具体代码reflect.Select如下所示(来自文章):// Run multiplexer until it receives an EOF on the control channel.func (mux *Multiplexer) Run() {    for {        index, value, recv := reflect.Select(mux.selectCases)        EOF := !recv        // note that the control channel is always at index 0        if index == 0 {            if EOF {                return            }            muxInput, _ := value.Interface().(*muxInputSource)            mux.selectCases = append(mux.selectCases, reflect.SelectCase{                Dir:  reflect.SelectRecv,                Chan: reflect.ValueOf(muxInput.collection),                Send: reflect.Value{},            })        } else {            if EOF {                mux.writeEOF()                mux.selectCases = append(mux.selectCases[:index], mux.selectCases[index+1:]...)            } else {                document, _ := value.Interface().([]byte)                mux.writeDocument(document)[]            }        }    }}我认为他们使用reflect.Select而不是直接的原因select:goroutine 的数量(以及通道的数量)是在运行时确定的(使用-j标志)。事实上,它似乎随着append. (归功于@cnicutar 的评论)通道的类型在运行时确定。这允许他们的muxInput.collection类型是任何它想要的。(归功于@JimB 的评论)

桃花长相依

如果您的频道是固定的,您可以使用选择观看它们;但是,如果您的频道不固定并且您想观看它们,则可以使用 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.ChildWatches、z.DataWatches、z.EphemeralNodes)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go