Gelagat Golang Pelik "tambah": Menimpa Nilai dalam Hiris
Di Golang, apabila dilampirkan pada kepingan, adalah penting untuk memahami perbezaan antara jenis penunjuk dan bukan penunjuk.
Pertimbangkan contoh kod:
import "fmt" type Foo struct { val int } func main() { var a = make([]*Foo, 1) a[0] = &Foo{0} var b = [3]Foo{Foo{1}, Foo{2}, Foo{3}} for _, e := range b { a = append(a, &e) } for _, e := range a { fmt.Printf("%v ", *e) } }
Output yang dijangkakan ialah {0} {1} {2} {3}, tetapi sebaliknya ia mencetak {0} {3} {3} {3}. Ini kerana gelung for beroperasi pada salinan elemen tatasusunan.
Apabila lelaran dengan julat untuk ..., pembolehubah gelung sementara dicipta dan diberikan nilai elemen tatasusunan. Dalam kes ini, pembolehubah sementara ialah jenis Foo. Walau bagaimanapun, apabila menambah pada kepingan, alamat pembolehubah sementara ditambah dan bukannya alamat elemen tatasusunan sebenar.
Pembolehubah sementara ini ditimpa dalam setiap lelaran gelung dengan nilai elemen terakhir bagi tatasusunan, iaitu Foo{3}. Hasilnya, hirisan mengandungi berbilang rujukan kepada penuding yang sama, menunjuk kepada elemen terakhir tatasusunan.
Untuk menyelesaikan isu, alamat elemen tatasusunan dan bukannya pembolehubah gelung hendaklah dilampirkan:
for i := range b { a = append(a, &b[i]) }
Dengan pengubahsuaian ini, output adalah seperti yang dijangkakan: {0} {1} {2} {3}.
Tingkah laku ini menyerlahkan kepentingan memahami sistem jenis Go dan perbezaan antara penunjuk dan bukan penunjuk apabila bekerja dengan kepingan.
Atas ialah kandungan terperinci Mengapa Menambahkan Penunjuk pada Slice in Go Menghasilkan Nilai Ditimpa Tidak Dijangka?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!