Ответ 1
Вы попробовали это?
Поп из очереди
x, a = a[0], a[1:]
Поп из стека
x, a = a[len(a)-1], a[:len(a)-1]
От себя
a = append(a, x)
Я создал простую очередь в Go. Он использует внутренний срез для отслеживания его элементов. Элементы помещаются в очередь, добавляя к срезу. Я хотел бы реализовать .Pop()
, удалив первый элемент в elements
.
Во многих других языках "выскакивание" первого элемента списка является однострочным, что заставляет меня полагать, что моя реализация ниже неаккуратная и многословная. Есть ли способ лучше?
type Queue struct {
elements []interface{}
}
func (queue *Queue) Push(element interface{}) {
queue.elements = append(queue.elements, element)
}
func (queue *Queue) Pop() interface{} {
element := queue.elements[0]
if len(queue.elements) > 1 {
queue.elements = queue.elements[1:]
} else {
queue.elements = make([]interface{}, 0)
}
return element
}
Обратите внимание, что я хочу, чтобы Queue
в панике, если len(queue.elements) == 0
. Это не недосмотр, что я не проверяю границы.
Вы попробовали это?
Поп из очереди
x, a = a[0], a[1:]
Поп из стека
x, a = a[len(a)-1], a[:len(a)-1]
От себя
a = append(a, x)
Если вам нужен кольцевой буфер или структура FIFO, то использование среза, как в ответе @Everton, вызовет проблемы с сборкой мусора, поскольку базовый массив может расти бесконечно.
Самый простой способ сделать это в go, если вы не против иметь ограниченный размер, - использовать канал, который также безопасен для одновременного доступа. Это такая распространенная идиома в том, что вы обычно не утруждаете ее упаковкой в виде, подобном приведенному ниже.
Например (детская площадка)
package main
import "fmt"
type Queue struct {
elements chan interface{}
}
func NewQueue(size int) *Queue {
return &Queue{
elements: make(chan interface{}, size),
}
}
func (queue *Queue) Push(element interface{}) {
select {
case queue.elements <- element:
default:
panic("Queue full")
}
}
func (queue *Queue) Pop() interface{} {
select {
case e := <-queue.elements:
return e
default:
panic("Queue empty")
}
return nil
}
func main() {
q := NewQueue(128)
q.Push(1)
q.Push(2)
q.Push(3)
fmt.Printf("Pop %d\n", q.Pop())
fmt.Printf("Pop %d\n", q.Pop())
fmt.Printf("Pop %d\n", q.Pop())
fmt.Printf("Pop %d\n", q.Pop())
}