Как лучше всего очистить фрагмент в Go?
Вот что я нашел на форумах го :
// test.go
package main
import (
"fmt"
)
func main() {
letters := []string{"a", "b", "c", "d"}
fmt.Println(cap(letters))
fmt.Println(len(letters))
// clear the slice
letters = letters[:0]
fmt.Println(cap(letters))
fmt.Println(len(letters))
}
Это верно?
Чтобы уточнить, буфер очищается, поэтому его можно использовать повторно.
Примером может служить функция Buffer.Truncate в пакете bytes.
Обратите внимание, что Reset просто вызывает Truncate (0). Похоже, что в этом случае строка 70 будет оценивать: b.buf = b.buf [0: 0]
http://golang.org/src/pkg/bytes/buffer.go
// Truncate discards all but the first n unread bytes from the buffer.
60 // It panics if n is negative or greater than the length of the buffer.
61 func (b *Buffer) Truncate(n int) {
62 b.lastRead = opInvalid
63 switch {
64 case n < 0 || n > b.Len():
65 panic("bytes.Buffer: truncation out of range")
66 case n == 0:
67 // Reuse buffer space.
68 b.off = 0
69 }
70 b.buf = b.buf[0 : b.off+n]
71 }
72
73 // Reset resets the buffer so it has no content.
74 // b.Reset() is the same as b.Truncate(0).
75 func (b *Buffer) Reset() { b.Truncate(0) }
Ответы:
Все зависит от того, что вы понимаете под словом «ясный». Один из верных, безусловно, таков:
Но есть загвоздка. Если элементы среза относятся к типу T:
затем принуждение
len(slice)
к нулю с помощью вышеупомянутой "уловки" не делает ни одного элементаимеет право на сборку мусора. В некоторых сценариях это может быть оптимальным подходом. Но это также может быть причиной «утечек памяти» - память не используется, но потенциально доступна (после повторного нарезания «фрагмента») и, следовательно, не может «собираться» мусором.
источник
Установка среза
nil
- лучший способ очистить срез.nil
срезы в go работают отлично, и установка срезаnil
высвобождает базовую память сборщику мусора.Посмотреть детскую площадку
Печать
Обратите внимание, что срезы могут быть легко наложены на псевдонимы, так что два среза указывают на одну и ту же базовую память. При
nil
выборе значения этот псевдоним будет удален.Однако этот метод изменяет емкость на ноль.
источник
append
ing to anil
slice всегда работал в Go?Я немного разбирался в этом вопросе для своих целей; У меня был кусок структур (включая некоторые указатели), и я хотел убедиться, что все правильно понял; попал в эту ветку и хотел поделиться своими результатами.
Для практики я устроил небольшую площадку для игр: https://play.golang.org/p/9i4gPx3lnY
что соответствует этому:
Запуск этого кода как есть покажет один и тот же адрес памяти для переменных «meow» и «meow2» как одинаковые:
что, я думаю, подтверждает, что структура собирает мусор. Как ни странно, раскомментирование закомментированной строки печати даст разные адреса памяти для мяуканья:
Я думаю, это может быть из-за того, что печать каким-то образом откладывается (?), Но интересная иллюстрация некоторого поведения управления памятью и еще один голос за:
источник
0x1030e0c0
не равно0x1030e0f0
(первое заканчивается наc0
, второе - наf0
).meow2
каждого запуска ...