Rumah >pembangunan bahagian belakang >Golang >Mengapa Menyalin Go Slice Tidak Mencipta Salinan Dalam, dan Bagaimana Saya Boleh Mengelakkan Mutasi Yang Tidak Diingini?

Mengapa Menyalin Go Slice Tidak Mencipta Salinan Dalam, dan Bagaimana Saya Boleh Mengelakkan Mutasi Yang Tidak Diingini?

Patricia Arquette
Patricia Arquetteasal
2024-11-27 18:38:14524semak imbas

Why Does Copying a Go Slice Not Create a Deep Copy, and How Can I Avoid Unintended Mutations?

Memahami Kebolehubahan Slice dalam Go

In Go, slice ialah pembolehubah bersaiz dinamik yang menyimpan jujukan unsur yang bersebelahan. Ia dilaksanakan menggunakan struktur pengepala yang menyimpan panjang dan penuding kepada tatasusunan asas yang mengandungi elemen.

Pertimbangkan coretan kod berikut:

func someFunc(A []int) int {
    ...
    tempA := A // copy the slice by value
    ...
    newArr = remove(tempA, i)
    ...
}

func remove(slice []int, s int) []int {
    return append(slice[:s], slice[s+1:]...)
}

Dalam kod ini, fungsi tambah digunakan untuk mengubah suai kepingan tempA. Walau bagaimanapun, apabila fungsi someFunc kembali, kepingan A asal juga diubah suai, walaupun pada hakikatnya tempA dicipta sebagai salinan A.

Mengapa ini berlaku?

Pengepala hirisan ialah struktur data yang berasingan daripada tatasusunan asas. Apabila hirisan disalin, hanya pengepala disalin, bukan tatasusunan asas. Ini bermakna hirisan A asal dan hirisan tempA yang baru dicipta kedua-duanya menghala ke tatasusunan asas yang sama.

Apabila fungsi tambah dipanggil, hirisan baharu dicipta dan unsur hirisan tempA disalin ke dalam kepingan baru. Walau bagaimanapun, kepingan A masih menunjuk kepada tatasusunan asas yang sama, yang kini mengandungi unsur-unsur yang diubah suai.

Cadangan

Untuk mengelakkan mutasi yang tidak diingini pada kepingan asal apabila mengubah suai salin, anda harus menggunakan fungsi salin untuk membuat salinan dalam kepingan. Fungsi salin mencipta tatasusunan asas baharu dan menyalin elemen ke dalamnya.

Berikut ialah contoh cara menggunakan fungsi salin:

tempA := make([]int, len(A))
copy(tempA, A)

Ini akan mencipta tatasusunan asas baharu untuk tempA dan salin elemen dari A ke dalamnya. Sebarang pengubahsuaian yang dibuat pada tempA tidak akan menjejaskan kepingan A asal.

Atas ialah kandungan terperinci Mengapa Menyalin Go Slice Tidak Mencipta Salinan Dalam, dan Bagaimana Saya Boleh Mengelakkan Mutasi Yang Tidak Diingini?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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