简体   繁体   中英

Assigning a variable of reference type “slice” to another variable, why don't they change simultaneously?

anotherSlice := theSlice
anotherSlice = append(anotherSlice, newEle)
fmt.Println(len(anotherSlice) == len(theSlice))

This snippet will output false . Why?

And here are some other experiments:

package main

import "fmt"

func main() {
    theSlice := []int{3,3,2,5,12,43}
    anotherSlice := theSlice
    fmt.Println(anotherSlice[3], theSlice[3])
    anotherSlice[3] = anotherSlice[3]+2
    fmt.Println(anotherSlice[3], theSlice[3])
    anotherSlice = append(anotherSlice[:3], anotherSlice[4:]...)
    fmt.Println(len(anotherSlice),len(theSlice))
}

The output is like below:

5 5
7 7
5 6

Program exited.

Whenever appended slice anotherSlice has no capacity for the new element, append function creates new slice and returns it. Since then the slices anotherSlice and theSlice are different - they are backed by separate arrays.

Reslicing slice with a shorter length anotherSlice[:3] has no impact on the original capacity of the slice.

The following line:

anotherSlice = append(anotherSlice[:3], anotherSlice[4:]...)

cuts out fourth (index 3) element. Because anotherSlice[:3] has capacity to hold all elements of anotherSlice[4:] no new allocation happens and therefore both slices are modified.

package main

import (
        "fmt"
)   

func main() {
        x := []int{1, 2, 3, 4, 5, 6}
        fmt.Println(cap(x[:3]) >= len(x[:3])+len(x[4:]))
        y := append(x[:3], x[4:]...)
        fmt.Println(x, y)
}

Playground

The answer to why the length of one slice doesn't follow the change to another slice's length change is not related to the underlying storage potentially being copied and/or modified.

In Go, it is important to remember what a slice is. It is a struct with a length field, a capacity field, and a pointer to an array. Some operations change the length field. Some change the capacity field. Some change the data stored in the underlying array.

If one doesn't grasp how a slice is implemented in the language, there will be all sorts of confusion and bugs and wasted opportunities. Once one becomes comfortable with how a slice is implemented, they are very easy to use and the fact that the compiler understands the structure of the slice, some very elegant and easily read code can be written.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM