亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

reflect.Select 函數是需要為什么?我認為這是因為通道必須是反射值?

reflect.Select 函數是需要為什么?我認為這是因為通道必須是反射值?

Go
UYOU 2022-01-17 18:17:32
在什么情況下會需要reflect.Select?我找到了例子,但 Select 的使用似乎是做作的。任何示例,其中 reflect.Select 比正常選擇是必要的?
查看完整描述

2 回答

?
侃侃無極

TA貢獻2051條經驗 獲得超10個贊

最近有一篇來自 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 的評論)


查看完整回答
反對 回復 2022-01-17
?
桃花長相依

TA貢獻1860條經驗 獲得超8個贊

如果您的頻道是固定的,您可以使用選擇觀看它們;但是,如果您的頻道不固定并且您想觀看它們,則可以使用 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)


查看完整回答
反對 回復 2022-01-17
  • 2 回答
  • 0 關注
  • 281 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號