Is there a queue implementation?

后端 未结 14 1178
时光取名叫无心
时光取名叫无心 2020-12-23 02:14

Can anyone suggest Go container for simple and fast FIF/queue, Go has 3 different containers: heap, list and vector. Which one is more

14条回答
  •  青春惊慌失措
    2020-12-23 02:59

    Unfortunately queues aren't currently part of the go standard library, so you need to write your own / import someone else's solution. It's a shame as containers written outside of the standard library aren't able to use generics.

    A simple example of a fixed capacity queue would be:

    type MyQueueElement struct {
      blah int // whatever you want
    }
    
    const MAX_QUEUE_SIZE = 16
    type Queue struct {
      content  [MAX_QUEUE_SIZE]MyQueueElement
      readHead int
      writeHead int
      len int
    }
    
    func (q *Queue) Push(e MyQueueElement) bool {
      if q.len >= MAX_QUEUE_SIZE {
        return false
      }
      q.content[q.writeHead] = e
      q.writeHead = (q.writeHead + 1) % MAX_QUEUE_SIZE
      q.len++
      return true
    }
    
    func (q *Queue) Pop() (MyQueueElement, bool) {
      if q.len <= 0 {
        return MyQueueElement{}, false
      }
      result := q.content[q.readHead]
      q.content[q.readHead] = MyQueueElement{}
      q.readHead = (q.readHead + 1) % MAX_QUEUE_SIZE
      q.len--
      return result, true
    }
    

    Gotchas avoided here include not having unbounded slice growth (caused by using the slice [1:] operation to discard), and zeroing out popped elements to ensure their contents are available for garbage collection. Note, in the case of a MyQueueElement struct containing only an int like here, it will make no difference, but if struct contained pointers it would.

    The solution could be extended to reallocate and copy should an auto growing queue be desired.

    This solution is not thread safe, but a lock could be added to Push/Pop if that is desired.

    Playground https://play.golang.org/

提交回复
热议问题