Jaki jest właściwy sposób na usunięcie kawałka w Go?
Oto, co znalazłem na forach 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))
}
Czy to jest poprawne?
Aby wyjaśnić, bufor jest czyszczony, aby można go było ponownie wykorzystać.
Przykładem jest funkcja Buffer.Truncate w pakiecie bajtów.
Zauważ, że Reset wywołuje po prostu Truncate (0). Wygląda więc na to, że w tym przypadku wiersz 70 wyliczyłby: 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) }
Odpowiedzi:
Wszystko zależy od tego, jaka jest Twoja definicja „jasności”. Jednym z ważnych z pewnością jest:
Ale jest haczyk. Jeśli elementy plastra są typu T:
następnie wymuszenie wartości
len(slice)
zero przez powyższą "sztuczkę" nie tworzy żadnego elementukwalifikuje się do czyszczenia pamięci. To może być optymalne podejście w niektórych scenariuszach. Ale może to być również przyczyną „wycieków pamięci” - pamięć nieużywana, ale potencjalnie dostępna (po ponownym pocięciu „plasterka”), a zatem nie „śmieciowa” do „zbierania”.
źródło
Ustawienie plasterka
nil
to najlepszy sposób na wyczyszczenie plastra.nil
plastry w ruchu zachowują się doskonale, a ustawienie tego plasterkanil
spowoduje zwolnienie podstawowej pamięci do modułu odśmiecania pamięci.Zobacz plac zabaw
Wydruki
Zauważ, że plasterki można łatwo aliasować, tak aby dwa wycinki wskazywały na tę samą pamięć podstawową. Ustawienie na
nil
usunie aliasing.Ta metoda zmienia jednak pojemność na zero.
źródło
append
robienienil
kawałka zawsze działało w Go?Przyglądałem się temu zagadnieniu trochę dla własnych celów; Miałem kawałek struktur (w tym kilka wskazówek) i chciałem się upewnić, że zrobiłem to dobrze; trafiłem na ten wątek i chciałem podzielić się moimi wynikami.
Aby poćwiczyć, zrobiłem mały plac zabaw: https://play.golang.org/p/9i4gPx3lnY
co odpowiada temu:
Uruchomienie tego kodu w niezmienionej postaci pokaże ten sam adres pamięci dla zmiennych „meow” i „meow2” jako taki sam:
co, jak sądzę, potwierdza, że struktura jest zbierana jako śmieci. Co dziwne, odkomentowanie komentowanej linii wydruku przyniesie różne adresy pamięci dla miauknięć:
Myślę, że może to być spowodowane odroczeniem wydruku w jakiś sposób (?), Ale interesującą ilustracją niektórych zachowań zarządzania pamięcią i jeszcze jednym głosem na:
źródło
0x1030e0c0
nie są równe0x1030e0f0
(pierwszy kończy się nac0
, drugi naf0
).meow2
każdego uruchomienia ...