任何人都可以解释这种附加到golang切片的奇怪行为

The program below has unexpected output.

func main(){
    s:=[]int{5}
    s=append(s,7)
    s=append(s,9)
    x:=append(s,11)
    y:=append(s,12)
    fmt.Println(s,x,y)
}

output: [5 7 9] [5 7 9 12] [5 7 9 12]

Why is the last element of x 12?

A slice is only a window over part of an array, it has no specific storage.

This means that if you have two slices over the same part of an array, both slices must "contain" the same values.

Here's exactly what happens here :

  1. When you do the first append, you get a new slice of size 2 over an underlying array of size 2.
  2. When you do the next append, you get a new slice of size 3 but the underlying array is of size 4 (append usually allocates more space than the immediately needed one so that it doesn't need to allocate at every append).
  3. This means the next append doesn't need a new array. So x and y both will use the same underlying array as the precedent slice s. You write 11 and then 12 in the same slot of this array, even if you get two different slices (remember, they're just windows).

You can check that by printing the capacity of the slice after each append :

fmt.Println(cap(s))

If you want to have different values in x and y, you should do a copy, for example like this :

s := []int{5}
s = append(s, 7)
s = append(s, 9)
x := make([]int,len(s))
copy(x,s)
x = append(x, 11)
y := append(s, 12)
fmt.Println(s, x, y)

Another solution here might have been to force the capacity of the array behind the s slice to be not greater than the needed one (thus ensuring the two following append have to use a new array) :

s := []int{5}
s = append(s, 7)
s = append(s, 9)
s = s[0:len(s):len(s)]
x := append(s, 11)
y := append(s, 12)
fmt.Println(s, x, y)

See also Re-slicing slices in Golang

dystroy explained it very well. I like to add a visual explanation to the behaviour.

A slice is only a descriptor of an array segment. It consists of a pointer to the array (ptr), the length of the segment (len), and capacity (cap).

    +-----+                                                              
    | ptr |                                                              
    |*Elem|                                                              
    +-----+                                                              
    | len |                                                              
    |int  |                                                              
    +-----+                                                              
    | cap |                                                              
    |int  |                                                              
    +-----+ 

So, the explanation of the code is as follow;

func main() {                                                           
                      +                                                 
                      |                                                 
  s := []int{5}       |  s -> +-----+                                   
                      | []int | ptr +-----> +---+                       
                      |       |*int | [1]int| 5 |                       
                      |       +-----+       +---+                       
                      |       |len=1|                                   
                      |       |int  |                                   
                      |       +-----+                                   
                      |       |cap=1|                                   
                      |       |int  |                                   
                      |       +-----+                                   
                      |                                                 
  s = append(s,7)     |  s -> +-----+                                   
                      | []int | ptr +-----> +---+---+                   
                      |       |*int | [2]int| 5 | 7 |                   
                      |       +-----+       +---+---+                   
                      |       |len=2|                                   
                      |       |int  |                                   
                      |       +-----+                                   
                      |       |cap=2|                                   
                      |       |int  |                                   
                      |       +-----+                                   
                      |                                                 
  s = append(s,9)     |  s -> +-----+                                   
                      | []int | ptr +-----> +---+---+---+---+           
                      |       |*int | [4]int| 5 | 7 | 9 |   |           
                      |       +-----+       +---+---+---+---+           
                      |       |len=3|                                   
                      |       |int  |                                   
                      |       +-----+                                   
                      |       |cap=4|                                   
                      |       |int  |                                   
                      |       +-----+                                   
                      |                                                 
  x := append(s,11)   |          +-------------+-----> +---+---+---+---+
                      |          |             | [4]int| 5 | 7 | 9 |11 |
                      |          |             |       +---+---+---+---+
                      |  s -> +--+--+  x -> +--+--+                     
                      | []int | ptr | []int | ptr |                     
                      |       |*int |       |*int |                     
                      |       +-----+       +-----+                     
                      |       |len=3|       |len=4|                     
                      |       |int  |       |int  |                     
                      |       +-----+       +-----+                     
                      |       |cap=4|       |cap=4|                     
                      |       |int  |       |int  |                     
                      |       +-----+       +-----+                     
                      |                                                 
  y := append(s,12)   |                        +-----> +---+---+---+---+
                      |                        | [4]int| 5 | 7 | 9 |12 |
                      |                        |       +---+---+---+---+
                      |                        |                        
                      |          +-------------+-------------+          
                      |          |             |             |          
                      |  s -> +--+--+  x -> +--+--+  y -> +--+--+       
                      | []int | ptr | []int | ptr | []int | ptr |       
                      |       |*int |       |*int |       |*int |       
                      |       +-----+       +-----+       +-----+       
                      |       |len=3|       |len=4|       |len=4|       
                      |       |int  |       |int  |       |int  |       
                      |       +-----+       +-----+       +-----+       
                      |       |cap=4|       |cap=4|       |cap=4|       
                      |       |int  |       |int  |       |int  |       
                      +       +-----+       +-----+       +-----+       
  fmt.Println(s,x,y)                                                    
}