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

use*_*227 10 arrays go slice

下面的程序有意想不到的输出.

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)
}
Run Code Online (Sandbox Code Playgroud)

输出: [5 7 9] [5 7 9 12] [5 7 9 12]

为什么是最后一个元素x 12

Den*_*ret 11

切片只是数组的一部分窗口,没有特定的存储空间.

这意味着如果在阵列的同一部分上有两个切片,则两个切片必须"包含"相同的值.

这里到底发生了什么:

  1. 当您执行第一个操作时append,您将获得一个大小2的基础数组的新切片大小2.
  2. 当您执行下一个操作时append,您将获得一个新的大小片段,3但是底层数组的大小4(append通常分配比立即需要的空间更多的空间,以便它不需要在每次追加时分配).
  3. 这意味着下一个append不需要新的数组.因此x,y两者都将使用与先前切片相同的底层数组s.你编写11然后12在这个数组的同一个插槽中,即使你得到两个不同的切片(记住,它们只是窗口).

您可以通过在每次追加后打印切片的容量来检查:

fmt.Println(cap(s))
Run Code Online (Sandbox Code Playgroud)

如果你想在x和中有不同的值y,你应该做一个副本,例如:

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)
Run Code Online (Sandbox Code Playgroud)

这里的另一个解决方案可能是强制s切片后面的数组的容量不大于所需的容量(从而确保以下两个append 必须使用新数组):

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)
Run Code Online (Sandbox Code Playgroud)

另请参阅在Golang中重新切片


Alp*_*per 8

Dystroy 解释得很好。我喜欢为行为添加视觉解释。

切片只是数组段的描述符。它由指向数组的指针 (ptr)、段的长度 (len) 和容量 (cap) 组成。

    +-----+                                                              
    | ptr |                                                              
    |*Elem|                                                              
    +-----+                                                              
    | len |                                                              
    |int  |                                                              
    +-----+                                                              
    | cap |                                                              
    |int  |                                                              
    +-----+ 
Run Code Online (Sandbox Code Playgroud)

那么,代码的解释如下;

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)                                                    
} 
Run Code Online (Sandbox Code Playgroud)