Penimpaan Tidak Diinginkan dalam Fungsi "tambah" Go
Dalam Go, meneroka nuansa penambahan pada kepingan kadangkala boleh membawa kepada hasil yang tidak dijangka. Mari kita teliti contoh yang mempamerkan tingkah laku ini.
Pertimbangkan kod berikut:
import "fmt" type Foo struct { val int } func main() { a := make([]*Foo, 1) a[0] = &Foo{0} 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) } }
Menariknya, bukannya mencetak {0} {1} {2} {3}, output dibaca sebagai {0} {3} {3} {3}. Untuk merungkai teka-teki ini, mari kita rungkai fungsi "tambah".
Dalam Go, "tambah" menjangkakan penuding pada hirisan yang kita tambahkan elemen. Dalam contoh kami, kami menyimpan penunjuk kepada kejadian "Foo" dengan betul dalam hirisan "a."
Walau bagaimanapun, apabila menggelung melalui elemen tatasusunan "b," kami menghadapi isu yang halus. Sintaks "julat" berulang pada salinan setiap elemen dan bukannya elemen sebenar itu sendiri. Akibatnya, kami secara konsisten menambahkan penunjuk pada salinan contoh "Foo" "e," yang menunjuk kepada "Foo{3}" dalam lelaran akhir.
Untuk membetulkan gelagat ini, kami perlu merujuk elemen sebenar "b" dalam operasi "tambah" kami:
for i := range b { a = append(a, &b[i]) }
Pengubahsuaian ini memastikan kami menambah penunjuk terus kepada elemen dalam "b," menghasilkan output yang diingini: {0} {1} {2} {3}.
Memahami sebab asas tingkah laku ini adalah penting. Dalam Go, penunjuk ialah nilai, ditafsirkan sebagai alamat memori apabila memanipulasi data. Oleh itu, gelung "julat" berulang ke atas salinan nilai dan bukannya objek asal. Pengetahuan ini membantu memahami sebab dalam kod awal kami, tiga elemen menunjuk kepada contoh "Foo{3}" yang sama.
Atas ialah kandungan terperinci Mengapakah Fungsi `tambah` Go Menghasilkan Keputusan Yang Tidak Dijangka Apabila Menambah Penunjuk daripada Gelung Julat?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!