一、基于slice,简单实现
queue []*wantConn
//入队
queue = append(queue, w)
//出队
v := queue[0]
queue[0] = nil
queue = queue[1:]
- 但是这会存在问题,随着频繁的入队与出队操作,切片queue的底层数组,会有大量空间无法复用而造成浪费。除非该切片执行了扩容操作。扩容底层会新创建一个数组。
二、高阶处理方法
func (q *wantConnQueue) pushBack(w *wantConn) {
q.tail = append(q.tail, w) //尾部队列,入
}
func (q *wantConnQueue) popFront() *wantConn {
if q.headPos >= len(q.head) { //若读取位置超出头部出队列长度
if len(q.tail) == 0 {
return nil
}
// Pick up tail as new head, clear tail.
q.head, q.headPos, q.tail = q.tail, 0, q.head[:0]
}
w := q.head[q.headPos]
q.head[q.headPos] = nil //头部队列,出,并将该位置赋为nil
q.headPos++ //记录当前队列移动到的位置
return w
}
使用了两个切片head和tail;head切片用于出队操作,tail切片用于入队操作;
出队时,通过headPos读取位置,判断head切片是否消耗完,headPos > len(head) 即head每个位置为nil,则交换head与tail。
通过这种方式,Golang实现了底层数组空间的复用。