douji2520 2017-07-11 21:04
浏览 4

去:在选择和中断中过滤事件

This is the code I have so far:

for {
    select {
    case event := <-events:
        if event.Msg != nil && len(activeFilters) > 0 {
            //filter for messages
            matches := false
            for k, v := range activeFilters {
                if k == event.Msg.Namepace {                        
                  for _, code := range v {
                    if code != event.Msg.Code {
                        matches = true    
                        break //BREAK1
                    }
                  }
                  if matches {
                    break //BREAK2
                  }
                }
            }
            if !matches {
              break //BREAK3
            }
        }
        if err := sendEvent(event); err != nil {
            sendErr(err)
            return
        }
    case <-closed:
        return
    }
}

First, I am a beginner in Go. The above code generally looks too complex for me, I guess it can be optimized.

What I want to do: when an event arrives, I want to check if a given Code is inside a list of filters. The filters have two "dimensions": a namespace and a list of codes. activeFilters is a map[string][]uint64. (Note: I am allowed to redesign activeFilters to some other structure).

So I just want to prevent the code to execute sendEvent if the filter doesn't match, while sendEvent should be executed if the protocol matches any key in activeFilters AND the message code is contained in the value array for that key.

So can the above code be simplified? Is the usage of break (BREAK1 and BREAK2) correct? BREAK2 seems to be needed for me because the inner for loop may already find a match, in which case there's no need to continue iterating on activeFilters.

And finally, am I correct in using BREAK3? My thinking there is that if there is no match, I do not want to execute sendEvent, so I want to jump out of the case. In my limited Go understanding, using return there would close the channel or something like that....

:blush

  • 写回答

1条回答 默认 最新

  • duandian8251 2017-07-11 21:15
    关注

    If activeFilters is a map, you don't need to iterate it to find a key - that's the whole point of a map. You can just:

    if v,ok := activeFilters[event.Msg.Namepace]; ok {
        // range over v as you are now
    } else {
        // event.Msg.Namepace does not exist in the map
    }
    

    This eliminates one loop, and thus one break. The last break (BREAK 3) works but isn't particularly clear what it's doing; I'd make it a conditional to make it more readable:

    if matches {
        if err := sendEvent(event); err != nil {
            sendErr(err)
            return
        }
    }
    

    return would not close the channel (assuming there's another reference to it somewhere else, which there would have to be for this to work at all), but it would exit your loop, so no further messages would be processed. I'd also double-check that the return in the error case is really what you want; typically in these situations you'd log the error but keep handling future messages that come over the channel.

    评论

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题