Rumah > pembangunan bahagian belakang > Golang > Mengapakah penambahan pada salinan kepingan Go turut mengubah suai kepingan asal?

Mengapakah penambahan pada salinan kepingan Go turut mengubah suai kepingan asal?

Patricia Arquette
Lepaskan: 2024-11-20 14:53:14
asal
639 orang telah melayarinya

Why does appending to a copy of a Go slice also modify the original slice?

Memahami Slice Append dan Kesannya pada Slice Asal

Apabila bekerja dengan slice dalam Go, fungsi append sering digunakan untuk menambahkan elemen baharu kepada kepingan sedia ada. Walau bagaimanapun, ramai pembangun mungkin terkejut apabila mendapati bahawa operasi tambah ini juga boleh mengubah suai kepingan asal.

Kod Dalam Peperiksaan

Pertimbangkan coretan kod berikut:

func someFunc(A []int) int {
    for i := 0; i < len(A); i++ {
        tempA := A // copy the slice by value

        fmt.Println("A: ", A)
        fmt.Println("tempA: ", A)
        fmt.Println()

        newArr = remove(tempA, i)

        if isAesthetic(newArr) {
            ways++
        }
    }
}

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

Di sini, fungsi someFunc mengambil kepingan A sebagai input dan kemudian mencipta salinan A yang dipanggil tempA, sebelum menggunakan fungsi alih keluar untuk mengalih keluar elemen daripada tempA. Setelah memeriksa fungsi dalam tindakan, anda mungkin melihat output konsol berikut:

A:  [3 4 5 3 7]
tempA:  [3 4 5 3 7]

A:  [4 5 3 7 7]
tempA:  [4 5 3 7 7]

A:  [4 3 7 7 7]
tempA:  [4 3 7 7 7]

A:  [4 3 7 7 7]
tempA:  [4 3 7 7 7]
Salin selepas log masuk

Kesan Sampingan Mengejutkan

Semasa kod berjalan, ia mencetak kandungan kedua-dua A dan tempA, mendedahkan bahawa kepingan asal A juga diubah suai selepas lampiran dipanggil pada tempA. Tingkah laku ini mungkin kelihatan berlawanan dengan intuisi pada pandangan pertama, kerana anda menjangkakan salinan nilai kecil A adalah bebas daripada sebarang perubahan yang dibuat pada tempA.

Walau bagaimanapun, fenomena ini adalah akibat langsung daripada cara hirisan dilaksanakan dalam Go. Slices pada asasnya ialah struktur data ringan yang terdiri daripada pengepala dan penuding kepada tatasusunan asas. Pengepala termasuk maklumat tentang panjang dan kapasiti kepingan, manakala penuding menghala ke elemen pertama dalam kepingan.

Apabila anda menetapkan nilai A kepada tempA, anda pada asasnya mencipta pengepala kepingan baharu yang menghala ke tatasusunan asas yang sama seperti A. Oleh itu, sebarang perubahan yang dibuat pada tempA juga akan ditunjukkan dalam A, kerana kedua-dua kepingan merujuk kepada data yang sama.

Memahami Pengepala dan Tatasusunan Slice

Untuk memahami tingkah laku ini dengan lebih lanjut, ia membantu untuk memahami cara pengepala dan tatasusunan hirisan berinteraksi dalam Go. Tatasusunan mengandungi blok bersebelahan unsur-unsur jenis yang sama. Sekeping, sebaliknya, memberikan pandangan dinamik bagi bahagian tatasusunan. Ia menerangkan set elemen berturut-turut dalam tatasusunan, tetapi ia tidak memiliki data tatasusunan asas.

Apabila anda mencipta hirisan daripada tatasusunan menggunakan sintaks []T{e1, e2, ..., en}, anda pada asasnya mencipta pengepala kepingan baharu yang menunjuk kepada elemen pertama dalam tatasusunan. Panjang hirisan ditetapkan kepada n dan kapasiti ditetapkan kepada baki panjang tatasusunan selepas hirisan.

Begitu juga, apabila anda mencipta pengepala hirisan menggunakan sintaks []T(arr), anda sedang mencipta kepingan yang menunjuk kepada tatasusunan asas yang sama seperti arr. Panjang hirisan ditetapkan kepada panjang arr, dan kapasiti ditetapkan kepada kapasiti arr.

Implikasi dan Amalan Terbaik

Memahami hubungan antara kepingan dan tatasusunan boleh membantu anda mengelakkan kemungkinan perangkap dan menulis kod Go yang lebih cekap. Apabila bekerja dengan kepingan, ingat perkara berikut:

  • Elakkan memberikan kepingan kepada kepingan lain jika anda ingin mengekalkan rujukan bebas kepada tatasusunan asas yang sama.
  • Gunakan copy(dst , src) untuk mencipta kepingan baharu dengan pengepala berbeza sambil merujuk tatasusunan asas yang sama.
  • Pertimbangkan menggunakan fungsi make untuk mencipta kepingan dengan panjang dan kapasiti tertentu, mengelakkan overhed yang berpotensi memperuntukkan dan menyalin sesuatu tatasusunan asas baharu.

Memahami bahagian dalaman kepingan Go membolehkan anda memanfaatkan fleksibiliti dan kecekapannya sambil memastikan kod anda berfungsi seperti yang dimaksudkan. Dengan menerima nuansa pengepala dan tatasusunan hirisan, anda boleh menguasai seni menghiris dalam Go dan membuka kunci potensi penuh struktur data serba boleh ini.

Atas ialah kandungan terperinci Mengapakah penambahan pada salinan kepingan Go turut mengubah suai kepingan 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