Можно ли выделить пространство, занимаемое элементом среза, в Golang? - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь создать очередь, используя 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:]

1 Ответ

2 голосов
/ 26 марта 2020

queue - это фрагмент, который указывает на резервный массив. Неважно, насколько большая часть среза покрывает (или может покрывать при повторном размещении) резервный массив, пока есть ссылка на резервный массив, он будет храниться в памяти. Когда больше нет ссылок на него, сборщик мусора освободит его.

Когда вы добавляете новые элементы в queue, используя append(), если резервный массив не может вместить дополнительные элементы, он автоматически выделяет новый массив, копирует в него существующие элементы, и тогда старый массив больше не будет ссылаться на 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...)

В общем, я бы никогда этого не сделал. Если вы используете свою очередь, вы будете постоянно ставить в очередь и удалять элементы из очереди. Поэтому добавление элементов естественным образом сделает это возможным.

...