Rumah > pembangunan bahagian belakang > Golang > Mengapa Menghiris Semula Go Slice Menghasilkan Nilai Kapasiti Tidak Dijangka?

Mengapa Menghiris Semula Go Slice Menghasilkan Nilai Kapasiti Tidak Dijangka?

Barbara Streisand
Lepaskan: 2024-12-24 10:44:13
asal
688 orang telah melayarinya

Why Does Re-Slicing a Go Slice Result in Unexpected Capacity Values?

Menghiris Semula Hiris di Golang

Memahami tingkah laku hirisan boleh mengelirukan, terutamanya apabila penghirisan semula terlibat. Dalam coretan ini:

package main

import "fmt"

func main() {
    a := make([]int, 5)
    printSlice("a", a)
    b := make([]int, 0, 5)
    printSlice("b", b)
    c := b[:2]
    printSlice("c", c)
    d := c[2:5]
    printSlice("d", d)
}

func printSlice(s string, x []int) {
    fmt.Printf("%s len=%d cap=%d %v\n",
        s, len(x), cap(x), x)
}
Salin selepas log masuk

Output mendedahkan hasil yang tidak dijangka:

a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0] 
d len=3 cap=3 [0 0 0]
Salin selepas log masuk

Mengapa c mempunyai kapasiti 5 dan bukan 2? Untuk menjawabnya, kita perlu memahami konsep kepingan dalam Golang.

Kepingan ialah rujukan ringan kepada tatasusunan. Apabila kami membuat hirisan, kami menyediakan operasi julat (cth., [:2]) untuk menentukan indeks mula dan akhir tatasusunan yang dirujuk. Walau bagaimanapun, operasi julat ini tidak mencipta salinan tatasusunan asas. Sebaliknya, ia mencipta kepingan baharu yang berkongsi data asas yang sama.

Dalam contoh yang diberikan, b ialah kepingan kosong dengan kapasiti 5. Apabila kita mencipta c sebagai kepingan b dengan julat [ :2], kita pada asasnya mencipta rujukan kepada dua elemen pertama b. Memandangkan b mempunyai kapasiti 5, c berpotensi dikembangkan untuk memasukkan sehingga 5 elemen, walaupun hanya 2 elemen sedang dirujuk. Inilah sebabnya mengapa c mempunyai kapasiti 5 walaupun panjangnya ialah 2.

Tambahan pula, apabila kami mencipta d sebagai kepingan c dengan julat [2:5], kami secara berkesan mencipta kepingan yang berkongsi data asas yang sama seperti b, tetapi bermula dari indeks 2 dan melanjutkan sehingga indeks 5. Oleh kerana b mempunyai kapasiti 5, d mempunyai kapasiti 3 (5-2).

Atur cara berikut menggambarkan tingkah laku ini dengan lebih jelas:

func main() {
    b := make([]int, 0, 5)
    c := b[:2]
    d := c[1:5] // equivalent to d := b[1:5]
    d[0] = 1
    printSlice("c", c)
    printSlice("d", d)
}
Salin selepas log masuk

Output:

c len=2 cap=5 [0 1] // modifying d has modified c
d len=4 cap=4 [1 0 0 0] 
Salin selepas log masuk

Seperti yang anda lihat, mengubah suai d juga telah diubah suai c, menunjukkan bahawa c dan d adalah kedua-dua tetingkap di atas tatasusunan asas yang sama, b.

Atas ialah kandungan terperinci Mengapa Menghiris Semula Go Slice Menghasilkan Nilai Kapasiti Tidak Dijangka?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

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