Rumah > pembangunan bahagian belakang > Golang > Mengapa `reflect.Append` Reflection tidak mengubah suai Go Slice Asal?

Mengapa `reflect.Append` Reflection tidak mengubah suai Go Slice Asal?

Linda Hamilton
Lepaskan: 2024-11-26 06:11:25
asal
723 orang telah melayarinya

Why Doesn't Reflection's `reflect.Append` Modify the Original Go Slice?

Menambah pada Go Slice dengan Refleksi: Mendedahkan Isu Tersembunyi

Apabila menambahkan elemen baharu pada kepingan menggunakan pakej pantulan Go, tingkah laku yang tidak dijangka mungkin timbul di mana kepingan asal kekal tidak terjejas. Ini jelas dalam coretan kod berikut:

func appendToSlice(arrPtr interface{}) {
    valuePtr := reflect.ValueOf(arrPtr)
    value := valuePtr.Elem()
    value = reflect.Append(value, reflect.ValueOf(55))

    fmt.Println(value.Len()) // prints 1
}

func main() {
    arr := []int{}
    appendToSlice(&arr)
    fmt.Println(len(arr)) // prints 0
}
Salin selepas log masuk

Walaupun menambahkan elemen pada nilai yang dihiris, kepingan asal mengekalkan panjang asalnya sifar. Percanggahan yang membingungkan ini memerlukan sedikit penjelasan.

Refleksi dan Operasi Slice

Refleksi membolehkan kami memeriksa dan memanipulasi struktur data pada masa jalan, termasuk kepingan. Fungsi reflect.Append, serupa dengan append, mengambil nilai hirisan dan elemen baharu dan mengembalikan nilai hirisan baharu yang mengandungi elemen yang dikemas kini. Walau bagaimanapun, operasi ini tidak mengubah suai rujukan hirisan asal.

Dalam kod yang disediakan, pernyataan reflect.Append memberikan pantulan baharu. Nilai kepada pembolehubah nilai, menggantikan rujukan asal kepada hirisan dengan berkesan. Semasa nilai itu sendiri dikemas kini, penuding arr asal kekal tidak berubah, oleh itu panjang hirisan arr yang tidak diubah dalam fungsi utama.

Mengemas kini Slice Asal

Kepada kemas kini kepingan asal, kita perlu menggunakan kaedah Value.Set. Kaedah ini menggantikan nilai pada indeks yang ditentukan dalam nilai yang dihiris dengan nilai baharu. Dalam kes kami, kami perlu menggantikan keseluruhan kepingan dengan nilai baharu yang dikembalikan oleh reflect.Lampirkan:

func appendToSlice(arrPtr interface{}) {
    valuePtr := reflect.ValueOf(arrPtr)
    value := valuePtr.Elem()

    value.Set(reflect.Append(value, reflect.ValueOf(55)))

    fmt.Println(value.Len()) // prints 1
}
Salin selepas log masuk

Dengan pengubahsuaian ini, kepingan asal kini dikemas kini seperti yang ditunjukkan dalam output.

Kesimpulan

Melampirkan pada kepingan menggunakan pantulan memerlukan nuansa yang lebih sedikit daripada operasi tambah konvensional. Perkara utama ialah operasi pantulan berfungsi dengan salinan nilai dan untuk mengemas kini nilai asal, seseorang mesti menetapkannya secara eksplisit menggunakan kaedah Value.Set.

Atas ialah kandungan terperinci Mengapa `reflect.Append` Reflection tidak mengubah suai Go Slice Asal?. 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