【Go快速入门】深入理解append函数

在Go语言中,Slice属于最常用的数据结构之一,对其原理理解不清楚,很容易出现BUG,尤其是append函数,下面为详细解析:

先看代码:

/* 深入理解切片的append函数 */

package main

import "fmt"

func main(){
    s := []int{5}
    fmt.Println("s =", s, "len(s) =", len(s), "cap(s) =", cap(s), "ptr(s) =", &s[0])

    s = append(s,7)
    fmt.Println("s =", s, "len(s) =", len(s), "cap(s) =", cap(s), "ptr(s) =", &s[0])

    s = append(s,9) //每次扩容,内存都重新分配,旧的内存收回
    fmt.Println("s =", s, "len(s) =", len(s), "cap(s) =", cap(s), "ptr(s) =", &s[0])

    x := append(s, 11) //x的内存地址与s的内存地址是一样的
    fmt.Println("x =", x, "len(x) =", len(x), "cap(x) =", cap(x), "ptr(s) =", &s[0], "ptr(x) =", &x[0])

    y := append(s, 12) //y的内存地址与s的内存地址是一样的
    fmt.Println("y =", y, "len(y) =", len(y), "cap(y) =", cap(y), "ptr(s) =", &s[0], "ptr(y) =", &y[0])

}

输出结果为:

s = [5] len(s) = 1 cap(s) = 1 ptr(s) = 0xc000054080
s = [5 7] len(s) = 2 cap(s) = 2 ptr(s) = 0xc0000540d0
s = [5 7 9] len(s) = 3 cap(s) = 4 ptr(s) = 0xc0000520e0
x = [5 7 9 11] len(x) = 4 cap(x) = 4 ptr(s) = 0xc0000520e0 ptr(x) = 0xc0000520e0
y = [5 7 9 12] len(y) = 4 cap(y) = 4 ptr(s) = 0xc0000520e0 ptr(y) = 0xc0000520e0

出乎意料的是最后一步的结果,原以为再往s里追加数据,就要扩容了,但发现没有扩容,赋值直接覆盖了最后一个元素。

画个图来理解一下:
《【Go快速入门】深入理解append函数》

个人理解:s作为x和y的底层数组,x和y实际指向的是s的内存地址(都是对s的引用),如果直接对s做append操作时会考虑扩容,但是通过x和y来间接操作s的话,那么是不考虑扩容问题的,此时追加值且容量不够时,变成直接覆盖操作。

    原文作者:海阳之新
    原文地址: https://www.jianshu.com/p/41817336a7ff
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞