Rumah > pembangunan bahagian belakang > Golang > Mengapakah Fungsi `tambah` Go Menghasilkan Keputusan Yang Tidak Dijangka Apabila Menambah Penunjuk daripada Gelung Julat?

Mengapakah Fungsi `tambah` Go Menghasilkan Keputusan Yang Tidak Dijangka Apabila Menambah Penunjuk daripada Gelung Julat?

Patricia Arquette
Lepaskan: 2024-12-08 03:08:11
asal
151 orang telah melayarinya

Why Does Go's `append` Function Produce Unexpected Results When Appending Pointers from a Range Loop?

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)
    }
}
Salin selepas log masuk

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])
}
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan