Bagaimana cara menghapus kunci yang dipilih dari peta? Apakah aman digabungkan delete()
dengan rentang, seperti pada kode di bawah ini?
package main
import "fmt"
type Info struct {
value string
}
func main() {
table := make(map[string]*Info)
for i := 0; i < 10; i++ {
str := fmt.Sprintf("%v", i)
table[str] = &Info{str}
}
for key, value := range table {
fmt.Printf("deleting %v=>%v\n", key, value.value)
delete(table, key)
}
}
dictionary
for-loop
go
Everton
sumber
sumber
func (a T) expired() bool
antarmuka. Untuk keperluan contoh ini, Anda dapat mencoba:m := make(map[int]int)
/* populate m here somehow */
for key := range (m) {
if key % 2 == 0 { /* this is just some condition, such as calling expired */
delete(m, key);
}
}
Jawaban Sebastian akurat, tetapi saya ingin tahu mengapa itu aman, jadi saya melakukan penggalian ke dalam kode sumber Peta . Sepertinya pada panggilan ke
delete(k, v)
, itu pada dasarnya hanya menetapkan bendera (serta mengubah nilai hitungan) daripada benar-benar menghapus nilai:(Kosong adalah konstanta untuk nilainya
0
)Apa yang sebenarnya dilakukan oleh peta adalah mengalokasikan sejumlah ember tergantung pada ukuran peta, yang tumbuh saat Anda melakukan sisipan dengan laju
2^B
(dari kode sumber ini ):Jadi hampir selalu ada lebih banyak ember yang dialokasikan daripada yang Anda gunakan, dan ketika Anda melakukan
range
lebih dari peta, itu memeriksatophash
nilai setiap ember di2^B
dalamnya untuk melihat apakah dapat melompati itu.Untuk meringkas,
delete
dalam arange
aman karena data secara teknis masih ada, tetapi ketika memeriksatophash
itu melihat bahwa itu bisa melewatinya dan tidak memasukkannya dalamrange
operasi apa pun yang Anda lakukan. Kode sumber bahkan termasukTODO
:Ini menjelaskan mengapa menggunakan
delete(k,v)
fungsi ini sebenarnya tidak membebaskan memori, hanya menghilangkannya dari daftar bucket yang diizinkan untuk Anda akses. Jika Anda ingin mengosongkan memori yang sebenarnya, Anda harus membuat seluruh peta tidak dapat dijangkau sehingga pengumpulan sampah akan masuk. Anda dapat melakukan ini menggunakan garis sepertisumber
Saya bertanya-tanya apakah kebocoran memori bisa terjadi. Jadi saya menulis program uji:
Sepertinya GC memang membebaskan memori. Jadi tidak apa-apa.
sumber
Singkatnya, ya. Lihat jawaban sebelumnya.
Dan juga ini, dari sini :
Pertanyaan yang dia jawab adalah tentang memodifikasi elemen peta yang ada selama
range
operasi, itulah sebabnya dia menyebutkan "iterasi saat ini". Tetapi ini juga relevan di sini: Anda dapat menghapus kunci selama suatu rentang, dan itu berarti bahwa Anda tidak akan melihatnya nanti dalam rentang tersebut (dan jika Anda sudah melihatnya, tidak apa-apa).sumber