谁能解释这种附加到 golang 切片的奇怪行为

下面的程序有意外的输出。


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)

}

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


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


SMILET
浏览 194回答 2
2回答

慕容3067478

切片只是数组一部分的窗口,它没有特定的存储空间。这意味着如果在数组的同一部分有两个切片,则两个切片必须“包含”相同的值。这正是这里发生的事情:当您执行第一个操作时append,您将在一个大小2为基础的数组上获得一个新的大小切片2。当您执行 next 时append,您将获得一个新的大小切片,3但底层数组的大小4(append通常分配的空间比立即需要的空间多,因此不需要在每次追加时分配)。这意味着 nextappend不需要新数组。因此x,y两者都将使用与先例 slice 相同的底层数组s。你写11然后12在这个数组的同一个槽中,即使你得到两个不同的切片(记住,它们只是窗口)。您可以通过在每次 append 后打印切片的容量来检查:fmt.Println(cap(s))如果你想在xand 中有不同的值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)这里的另一个解决方案可能是强制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)

慕运维8079593

dystroy 很好地解释了它。我喜欢为行为添加视觉解释。切片只是数组段的描述符。它由指向数组的指针 (ptr)、段的长度 (len) 和容量 (cap) 组成。    +-----+                                                                  | ptr |                                                                  |*Elem|                                                                  +-----+                                                                  | len |                                                                  |int  |                                                                  +-----+                                                                  | cap |                                                                  |int  |                                                                  +-----+ 所以,代码的解释如下;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)                                                    } 
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go