golang实现可查找的FIFO队列

Andres-Lee 发布于 2013/08/11 15:10
阅读 3K+
收藏 2
Go

想实现一个可查找的队列,在网上找了半天没有找到这方面可参考的代码,无奈自己乱写了个。 初学,@astaxie 大神帮忙看看我写得这个有问题没? 谢谢!

package main

import (
	"container/list"
	"fmt"
	"reflect"
)

type Queue struct {
	sem  chan int
	list *list.List
}

var tFunc func(val interface{}) bool

func NewQueue() *Queue {
	sem := make(chan int, 1)
	list := list.New()
	return &Queue{sem, list}
}

func (q *Queue) Size() int {
	return q.list.Len()
}

func (q *Queue) Enqueue(val interface{}) *list.Element {
	q.sem <- 1
	e := q.list.PushFront(val)
	<-q.sem
	return e
}

func (q *Queue) Dequeue() *list.Element {
	q.sem <- 1
	e := q.list.Back()
	q.list.Remove(e)
	<-q.sem
	return e
}

func (q *Queue) Query(queryFunc interface{}) *list.Element {
	q.sem <- 1
	e := q.list.Front()
	for e != nil {
		if reflect.TypeOf(queryFunc) == reflect.TypeOf(tFunc) {
			if queryFunc.(func(val interface{}) bool)(e.Value) {
				<-q.sem
				return e
			}
		} else {
			<-q.sem
			return nil
		}
		e = e.Next()
	}
	<-q.sem
	return nil
}

func (q *Queue) Contain(val interface{}) bool {
	q.sem <- 1
	e := q.list.Front()
	for e != nil {
		if e.Value == val {
			<-q.sem
			return true
		} else {
			e = e.Next()
		}
	}
	<-q.sem
	return false
}

type Item struct {
	Key   string
	Value string
}

func main() {
	var v = Item{Key: "a", Value: "A"}
	queue := NewQueue()
	fmt.Println(queue.Enqueue(v).Value)
	v.Key = "b"
	v.Value = "B"
	fmt.Println(queue.Enqueue(v).Value)
	v.Key = "c"
	v.Value = "C"
	fmt.Println(queue.Enqueue(v).Value)
	v.Key = "d"
	v.Value = "D"
	fmt.Println(queue.Enqueue(v).Value)
	v.Key = "e"
	v.Value = "E"
	fmt.Println(queue.Enqueue(v).Value)

	fmt.Println(queue.Query(func(val interface{}) bool {
		if val.(Item).Key == "a" {
			return true
		} else {
			return false
		}
	}).Value)
	fmt.Println(queue.Contain(v))
	fmt.Println(queue.Dequeue().Value)
	fmt.Println(queue.Dequeue().Value)
	fmt.Println(queue.Dequeue().Value)
	fmt.Println(queue.Dequeue().Value)
}

加载中
0
mahone
mahone
大侠,我一直有个问题,顺便在这里问了。。。弱弱的问下,Go和golang,有什么区别?
Andres-Lee
Andres-Lee
回复 @mahone : 是的,两个说法。
mahone
mahone
@Andres-Lee 那为什么有2个名字?他们直接一点区别也没有?
Andres-Lee
Andres-Lee
一个东西。
0
astaxie
astaxie

sem  chan int

可以简单的直接用sync.Mutex,实现锁功能就好了,当然你这样用chan也没错,但是你这么简单的只要锁足以

Andres-Lee
Andres-Lee
嗯, 他们效率上有什么差别?
0
K
Klain

用chan来做锁

好有创意

0
_Leou
_Leou
队列没判空吗?
返回顶部
顶部