Gelagat Penambahan Slice Tidak Dijangka dalam Go
Dalam bidang pengaturcaraan Go, gelagat luar biasa telah ditemui apabila menambahkan elemen pada kepingan dalam gelung dan seterusnya cuba mencipta kepingan baharu berdasarkan hasil gelung. Menariknya, operasi tambah terakhir mengatasi hirisan yang dibuat daripada lampiran sebelumnya.
Meneroka Isu
Pertimbangkan coretan kod berikut:
<code class="go">func create(iterations int) []int { a := make([]int, 0) for i := 0; i < iterations; i++ { a = append(a, i) } return a }</code>
Apabila memanggil create(11) dan mencipta kepingan baharu dengan menambahkan elemen padanya (iaitu, j := append(i, 100), g := append(i, 101), h := append(i, 102)), one menjangkakan elemen terakhir bagi kepingan ini (j, g, dan h) masing-masing ialah 100, 101, dan 102. Walau bagaimanapun, yang menghairankan, dalam kes ini, kesemuanya akhirnya menjadi 102.
Tingkah laku ini sangat berbeza dengan apa yang berlaku apabila mencipta kepingan baharu daripada hirisan literal, seperti yang ditunjukkan di bawah:
<code class="go">func sliceFromLiteral() { i := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} j := append(i, 100) g := append(i, 101) h := append(i, 102) fmt.Printf("i: %v\nj: %v\ng: %v\nh:%v\n", i, j, g, h) }</code>
Dalam kes ini, j, g dan h mempamerkan gelagat yang dijangkakan, dengan elemen terakhir masing-masing ialah 100, 101 dan 102.
Menyelidiki Punca Punca
Untuk membongkar misteri di sebalik tingkah laku yang tidak dijangka ini, adalah penting untuk memahami bahawa operasi penambahan bukan sahaja mengubah suai tatasusunan tetapi juga mengembalikan kepingan baharu. Ini menunjukkan bahawa kepingan j, g, dan h sebenarnya menunjuk kepada tatasusunan asas yang sama. Oleh itu, apabila tambahan terakhir (tambah(i, 102)) dilakukan, ia mengubah suai elemen terakhir tatasusunan pendasar, mengatasi nilai dalam j, g dan h dengan berkesan.
Idiomatik Penyelesaian
Untuk mengelakkan tingkah laku yang tidak dijangka ini, adalah penting untuk menyalin kepingan sebelum mencuba sebarang tambahan. Melakukannya mencipta tatasusunan asas baharu, memastikan kepingan asal kekal tidak diubah suai. Kod berikut menunjukkan cara idiomatik mencipta berbilang kepingan baharu berdasarkan yang sedia ada:
<code class="go">func makeFromSlice(sl []int) []int { result := make([]int, len(sl)) copy(result, sl) return result }</code>
Dengan menggunakan pendekatan ini, seseorang boleh membuat kepingan baharu dengan mudah sambil mengekalkan integriti data asal.
Atas ialah kandungan terperinci Mengapakah kepingan yang dilampirkan dalam gelung mempamerkan gelagat yang tidak dijangka semasa membuat kepingan baharu dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!