为了账号安全,请及时绑定邮箱和手机立即绑定

我可以取消分配 Golang 中切片元素占用的空间吗?

我可以取消分配 Golang 中切片元素占用的空间吗?

Go
阿晨1998 2022-05-23 16:34:09
我正在尝试使用 Slice 实现队列。但是切片的问题在于,一旦切片,修剪后的元素会继续占用空间。因此,我想知道是否无论如何我可以删除占用的空间,或者换句话说,取消分配修剪元素的空间。queue := make([]int, 0)//Enqueuequeue = append(queue, 1)queue = append(queue, 2)queue = append(queue, 3)//DequeuedeletedElement := queue[0]//--unallocate the space occupied by queue[0]queue = queue[1:]
查看完整描述

1 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

queue是一个指向后备数组的切片。切片覆盖(或在重新切片时可能覆盖)后备数组的多大部分并不重要,只要有对后备数组的引用,它将被保存在内存中。当不再引用它时,垃圾收集器将释放它。


当你添加新元素到你的queueusingappend()时,如果后备数组不能容纳额外的元素,它会自动分配一个新数组,将现有元素复制到它,然后旧数组将不再被引用queue。如果没有其他对它的引用,它将被释放。


如果您不想等待这种情况发生,您唯一的选择是创建一个新数组或切片,将队列元素复制到其中,然后更新queue切片标题以指向这个新切片(所以旧的可以释放)。


例如:


//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...)

一般来说,我永远不会这样做。如果您使用队列,您将不断地排队和出列元素。所以添加元素自然会实现这一点。


查看完整回答
反对 回复 2022-05-23
  • 1 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号