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
Barbara Streisandasal
2024-12-24 10:44:13625semak imbas

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)
}

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]

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)
}

Output:

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

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