Apa cara yang tepat untuk membersihkan irisan di Go?
Inilah yang saya temukan di forum 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))
}
Apakah ini benar?
Untuk memperjelas, buffer dihapus sehingga dapat digunakan kembali.
Contohnya adalah fungsi Buffer.Truncate dalam paket byte.
Perhatikan bahwa Reset hanya memanggil Truncate (0). Jadi terlihat bahwa dalam kasus ini baris 70 akan mengevaluasi: 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) }
Jawaban:
Itu semua tergantung pada apa definisi Anda tentang 'jelas'. Salah satu yang valid tentunya adalah:
Tapi ada tangkapan. Jika elemen irisan berjenis T:
kemudian memaksakan
len(slice)
menjadi nol, dengan "trik" di atas, tidak membuat elemen apa punmemenuhi syarat untuk pengumpulan sampah. Ini mungkin pendekatan yang optimal dalam beberapa skenario. Tetapi ini juga bisa menjadi penyebab "kebocoran memori" - memori tidak digunakan, tetapi berpotensi dapat dijangkau (setelah pemotongan ulang 'irisan') dan dengan demikian bukan sampah "dapat dikoleksi".
sumber
Mengatur irisan ke
nil
adalah cara terbaik untuk membersihkan irisan.nil
slice yang sedang berjalan berperilaku sangat baik dan menyetel slice kenil
akan melepaskan memori yang mendasarinya ke pengumpul sampah.Lihat taman bermain
Cetakan
Perhatikan bahwa irisan dapat dengan mudah diberi alias sehingga dua irisan mengarah ke memori dasar yang sama. Pengaturan untuk
nil
akan menghapus aliasing itu.Metode ini mengubah kapasitas menjadi nol.
sumber
append
ing to anil
slice selalu berhasil di Go?Saya melihat masalah ini sedikit untuk tujuan saya sendiri; Saya memiliki sepotong struct (termasuk beberapa petunjuk) dan saya ingin memastikan bahwa saya melakukannya dengan benar; berakhir di utas ini, dan ingin membagikan hasil saya.
Untuk berlatih, saya melakukan sedikit bermain: https://play.golang.org/p/9i4gPx3lnY
yang menunjukkan ini:
Menjalankan kode itu apa adanya akan menampilkan alamat memori yang sama untuk variabel "meow" dan "meow2" sebagai:
yang menurut saya menegaskan bahwa struct adalah sampah yang dikumpulkan. Anehnya, menghapus komentar pada baris cetak yang dikomentari, akan menghasilkan alamat memori yang berbeda untuk meow:
Saya pikir ini mungkin karena pencetakan yang ditangguhkan dalam beberapa cara (?), Tetapi ilustrasi yang menarik dari beberapa perilaku manajemen memori, dan satu suara lagi untuk:
sumber
0x1030e0c0
tidak sama dengan0x1030e0f0
(yang pertama diakhiri denganc0
, yang terakhir masukf0
).meow2
setiap proses ...