Was ist der geeignete Weg, um ein Slice in Go zu löschen?
Folgendes habe ich in den Go-Foren gefunden :
// 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))
}
Ist das richtig?
Zur Verdeutlichung wird der Puffer gelöscht, damit er wiederverwendet werden kann.
Ein Beispiel ist die Funktion Buffer.Truncate im Byte-Paket.
Beachten Sie, dass Reset nur Truncate (0) aufruft. Es scheint also, dass in diesem Fall Zeile 70 Folgendes auswerten würde: 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) }
Antworten:
Es hängt alles davon ab, wie Sie "klar" definieren. Eine der gültigen ist sicherlich:
Aber da ist ein Fang. Wenn Slice-Elemente vom Typ T sind:
dann Durchsetzung
len(slice)
Null zu sein, durch die obigen „Trick“, nicht macht jedes Element vonberechtigt zur Müllabfuhr. Dies kann in einigen Szenarien der optimale Ansatz sein. Es kann aber auch eine Ursache für "Speicherlecks" sein - Speicher wird nicht verwendet, ist aber möglicherweise erreichbar (nach erneutem Schneiden von "Slice") und daher nicht "sammelbar".
quelle
Das Festlegen der Scheibe
nil
ist der beste Weg, um eine Scheibe zu löschen.nil
Slices in Go verhalten sich perfekt und wenn Sie das Slice sonil
einstellen , wird der zugrunde liegende Speicher für den Garbage Collector freigegeben.Siehe Spielplatz
Druckt
Beachten Sie, dass Slices leicht mit einem Alias versehen werden können, sodass zwei Slices auf denselben zugrunde liegenden Speicher verweisen. Die Einstellung zu
nil
entfernt dieses Aliasing.Diese Methode ändert die Kapazität jedoch auf Null.
quelle
append
nil
In Go hat immer ein Slice funktioniert?Ich habe mich ein wenig mit diesem Thema für meine eigenen Zwecke befasst. Ich hatte eine Reihe von Strukturen (einschließlich einiger Zeiger) und wollte sicherstellen, dass ich alles richtig gemacht habe. landete in diesem Thread und wollte meine Ergebnisse teilen.
Zum Üben habe ich einen kleinen Spielplatz besucht: https://play.golang.org/p/9i4gPx3lnY
was dazu führt:
Wenn Sie diesen Code so wie er ist ausführen, wird dieselbe Speicheradresse für die Variablen "meow" und "meow2" als identisch angezeigt:
was meiner Meinung nach bestätigt, dass die Struktur Müll gesammelt ist. Seltsamerweise ergibt das Kommentieren der kommentierten Druckzeile unterschiedliche Speicheradressen für die Miauen:
Ich denke, dies kann daran liegen, dass der Druck auf irgendeine Weise verschoben wurde (?), Aber eine interessante Illustration eines bestimmten Speicherverhaltens und eine weitere Stimme für:
quelle
0x1030e0c0
ist nicht gleich0x1030e0f0
(ersteres endet inc0
, letzteres inf0
).meow2
jedes Laufs ...