TGViewer
Go Update Go Update @go_update · 3.22K subscribers
Post #43 2.94K
🦎 proposal: slices: have Delete clear the tail

В своем докладе на GolangConf 2023 я буду рассказывать про эволюцию Go, в том числе и про новые пакеты в стандартной библиотеке. Изучая один из этих пакетов мне стало интересно, как там реализована функция Delete. А реализация там крайне простая:

func Delete[S ~[]E, E any](s S, i, j int) S {
_ = s[i:j] // bounds check

return append(s[:i], s[j:]...)
}

И вроде бы все верно, так? Даже те из вас, кто давно работают с Go скорее всего не смогут сходу сказать, что тут не так. Признаюсь, я к пониманию глубины проблемы пришел только в рамках подготовки самих слайдов.

Допустим у нас есть такой код:

 var slc []*int64
for i := 0; i < 10_000_000; i++ {
val := i
slc = append(slc, &val)
}

slc = slices.Delete(slc, 1, 10_000_000)

runtime.GC()

// Report memory metrics
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("Alloc = %v MiB\n", m.Alloc / 1024 / 1024)

Первичный анализ подсказывает, что после вызова GC у нас должен остаться в памяти слайс на 10 миллионов указателей и на один int. Ну т.е. программа в памяти будет занимать от 80 до 90 МБ на amd64.

Пробуем запустить и получаем вывод:

Alloc = 170 MiB

Наш анализ некорректен: в Go сборщик мусора не собирает память на которую есть указатели в активной памяти, даже если эти указатели находятся за пределами длинны слайса. Причина простая: никто не мешает вам сделать от слайса выше новый слайс с длинной 3 и тем самым восстановить указатель на 3ий элемент.

Интересно то, что этой проблемой озаботились не в Go Core Team, а простой Go разработчик-город-Тверь из Франции. Такую же проблему содержат и другие функции: DeleteFunc, Compact, CompactFunc и Replace.

При этом сам issue есть эталон того как это правильно делать: там и лаконичная мысль, разбитая на параграфы, и картинки которые круто визуализируют проблему, и разные варианты решений. В общем понравилось не только мне - Расс тоже оценил. А решение выбрал максимально простое: будем занулять элементы которые выкинули, благо у нас теперь есть встроенная функция clear.

Текущий статус: likely accept. А это значит, что пока есть все шансы, что мы увидим сие в 1.22.
GitHub slices: have Delete and others clear the tail · Issue #63393 · golang/go Proposal a = slices.Delete(a, i, j) should zero the (j - i) elements after the length of the returned slice TL;DR zeroing the elements is error-prone, it should be taken care of by the stdlib funct...
  • 👍 32
  • 🔥 11
  • ❤ 1
More from @go_update
  1. Aug 22, 2026Об изоляции LLM Да, это ещё один пост про работу с Codex/Claude/GLM/Qwen/DeepSeek и прочая…
  2. Aug 11, 2026И вот эти два минуса выглядят нерешенными (на данный момент времени). Можно ли их решить в…
  3. Aug 11, 2026🎂 Вечерний пост о том, что сегодня мне исполнилось 34. Прошёл еще один год, а значит врем…
  4. Jul 13, 2026📝 testing: allow examples with any signature Небольшое «Quality of Life» предложение. Сут…
  5. May 14, 2026📝 net/http/httptest: synctest support Я уже писал про пакет synctest и его возможности. Э…
  6. May 13, 2026Я редко пишу сюда о вещах которые не относятся к Go, но тут у меня появилась хорошая стать…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →