Golang 简单的FIFO队列实现
原文地址声明:https://blog.csdn.net/qq_23179075/article/details/118191460
定义队列操作函数接口 IQueue
type IQueue interface {
//Push 入队
Push(data IData)
//Pushs 一次性入队多个数据
Pushs(data []IData)
//Pop 出队
Pop() IData
//Get 获取队列中 index 位子的data
Get(index int) IData
//Set 设置队列中 index 位子的data
Set(index int, data IData) error
//Remove 设置队列中 index 位子的data
Remove(index int) IData
//RemoveAll 移除队列中的所有数据
RemoveAll()
//Size 当前队列大小
Size() int
//All 队列中的所有数据
All() []IData
//FindIndex 获取call返回为 true 第一个 index位子
FindIndex(call func(item IData) bool) int
}
预留 IData
数据接口
type IData interface{}
实现 BQueue
type BQueue struct {
Datas []IData
mutex sync.Mutex
}
//NewQueueFromDatas 通过data输出生成队列
func NewQueueFromDatas(datas []IData) *BQueue {
return &BQueue{Datas: datas}
}
//NewBQueue 初始化队列
func NewBQueue() *BQueue {
return &BQueue{Datas: []IData{}}
}
func (b *BQueue) Push(data IData) {
b.mutex.Lock()
defer b.mutex.Unlock()
b.Datas = append(b.Datas, data)
}
func (b *BQueue) Pushs(data []IData) {
b.mutex.Lock()
defer b.mutex.Unlock()
b.Datas = append(b.Datas, data...)
}
func (b *BQueue) Pop() IData {
b.mutex.Lock()
defer b.mutex.Unlock()
if len(b.Datas) <= 0 {
return nil
}
var data = b.Datas[0]
b.Datas = b.Datas[1:]
return data
}
func (b *BQueue) Get(index int) IData {
b.mutex.Lock()
defer b.mutex.Unlock()
if len(b.Datas) <= 0 {
return nil
}
if index < 0 || index >= len(b.Datas) {
return nil
}
return b.Datas[index]
}
func (b *BQueue) Set(index int, data IData) error {
b.mutex.Lock()
defer b.mutex.Unlock()
if index < 0 || index >= len(b.Datas) {
return fmt.Errorf(`index range of values [0,%v],index=%v`, len(b.Datas), index)
}
b.Datas[index] = data
return nil
}
func (b *BQueue) Remove(index int) IData {
b.mutex.Lock()
defer b.mutex.Unlock()
if len(b.Datas) == 0 {
return nil
}
if index < 0 || index >= len(b.Datas) {
return nil
}
data := b.Datas[index]
b.Datas = append(b.Datas[:index], b.Datas[index+1:]...)
return data
}
func (b *BQueue) RemoveAll() {
b.mutex.Lock()
defer b.mutex.Unlock()
b.Datas = make([]IData, 0)
}
func (b *BQueue) Size() int {
b.mutex.Lock()
defer b.mutex.Unlock()
return len(b.Datas)
}
func (b *BQueue) All() []IData {
return b.Datas
}
func (b *BQueue) FindIndex(call func(item IData) bool) int {
b.mutex.Lock()
defer b.mutex.Unlock()
for i, data := range b.Datas {
if call(data) {
return i
}
}
return -1
}
测试
package queue
import (
"fmt"
"testing"
)
type BData struct {
name string
age int
}
func TestBQueue(t *testing.T) {
datas := []IData{
&BData{name: "aaa", age: 12},
&BData{name: "bbbb", age: 11},
}
queue := NewQueueFromDatas(datas)
queue.Push(&BData{name: "CCC", age: 2})
queue.Push(&BData{name: "DDD", age: 2})
queue.Pushs([]IData{
&BData{name: "EEE", age: 12},
&BData{name: "FFF", age: 11},
})
err := queue.Set(2, &BData{name: "Haha", age: 3})
if err != nil {
fmt.Println(err)
}
err = queue.Set(10, &BData{name: "Haha", age: 3})
if err != nil {
fmt.Println("queue.Set(10): ", err)
}
for _, data := range queue.All() {
fmt.Print(data, ",")
}
fmt.Println()
index := queue.FindIndex(func(item IData) bool {
return item.(*BData).name == "EEE"
})
fmt.Println("queue.FindIndex(EEE): ",index)
fmt.Println("queue.Get(10): ", queue.Get(10))
fmt.Println("queue.Get(2): ", queue.Get(2))
fmt.Println("queue.Pop(): ", queue.Pop())
fmt.Println("queue.Get(2): ", queue.Get(2))
fmt.Println("queue.Pop(): ", queue.Pop())
fmt.Println("queue.Pop(): ", queue.Pop())
fmt.Println("queue.Pop(): ", queue.Pop())
fmt.Println("queue.Size(): ", queue.Size())
fmt.Println("queue.Pop(): ", queue.Pop())
fmt.Println("queue.Pop(): ", queue.Pop())
fmt.Println("queue.Pop(): ", queue.Pop())
}
=== RUN TestBQueue
queue.Set(10): index range of values [0,6],index=10
&{aaa 12},&{bbbb 11},&{Haha 3},&{DDD 2},&{EEE 12},&{FFF 11},
queue.FindIndex(EEE): 4
queue.Get(10):
queue.Get(2): &{Haha 3}
queue.Pop(): &{aaa 12}
queue.Get(2): &{DDD 2}
queue.Pop(): &{bbbb 11}
queue.Pop(): &{Haha 3}
queue.Pop(): &{DDD 2}
queue.Size(): 2
queue.Pop(): &{EEE 12}
queue.Pop(): &{FFF 11}
queue.Pop():
--- PASS: TestBQueue (0.00s)
PASS