我正在尝试使用Slice实现队列。但是切片的问题在于,切片后,修剪后的元素会继续占据空间。因此,我想知道是否仍然可以删除占用的空间,或者换句话说,不分配所修剪元素的空间。
queue := make([]int, 0)
//Enqueue
queue = append(queue, 1)
queue = append(queue, 2)
queue = append(queue, 3)
//Dequeue
deletedElement := queue[0]
//--unallocate the space occupied by queue[0]
queue = queue[1:]
queue
是一个切片,它指向一个后备数组。切片覆盖(或在切片时覆盖的)块有多大比例都没有关系,只要存在对数组的引用,它将被保存在内存中。当没有更多引用时,垃圾收集器将释放它。
[当您使用queue
将新元素添加到append()
时,如果后备数组无法容纳其他元素,它将自动分配一个新数组,将现有元素复制到该数组,然后旧数组将不会被queue
引用。如果没有其他引用,它将被释放。
如果您不想等待发生这种情况,则唯一的选择是创建一个新的数组或切片,将队列元素复制到其中,然后更新queue
slice标题以指向此新切片(这样可以释放旧的)。
例如:
//Dequeue
deletedElement := queue[0]
//--unallocate the space occupied by queue[0]
queue = queue[1:]
newQueue := make([]int, len(queue))
copy(newQueue, queue)
queue = newQueue
您可以稍微简化一下:
queue = append(make([]int, 0, len(queue)), queue...)
如您所见,这只是释放一个int
的空间的开销很大的操作。因此,仅在未使用的空间很大时,才应在每次出队后执行此操作。
还请注意,在创建新切片时,您可以使用更大的容量,因此可以在不引起立即重新分配的情况下将新元素放入队列,例如:
queue = append(make([]int, 0, 2* len(queue)), queue...)