append的用法 append函数的意思及用法

今天使用append函数时 , 遇到了一个小问题 , 所以深追了一下 , 和大家分享一下 。

append的用法 append函数的意思及用法

文章插图
努力工作的gopher
首先append是go语言内置的函数 , 作用就是为切片添加元素 , 常用操作如下:
s :=[]string{a,b}s=append(s,c)
结果我们打印s就会是:a , b , c 三个元素 。但是大家思考一下下面的代码:
s :=[]string{a, b, c}s1 :=append(s, d)fmt.Println(s1:, s1)fmt.Println(ss:, s)
这时我们打印的s1与s分别是多少呢?当然这个也难不倒大家 , 结果分别是:a b c d 和 a b c 。看到这里大家会想 , append函数 , 会将传件来的s从原来的地方拷贝一份 , 然后再把 d 这个元素放进去 , 变成 a b c d 再给到 s1 。当然目前看来可能是这样的 。那么我们再看下面的代码:
s :=[]string{a, b, c}s1 :=append(s[:2], d)fmt.Println(s1:, s1)fmt.Println(ss:, s)
这时打印的结果应该是什么呢?首先我们分析一下 , s[:2]这个操作 , 是截取了s中的前两个元素 , 也就是 a 和 b 。然后再把 d 添加进去 , 最后s1结果为: a b d 。这个是正确的 。
那么打印的s是什么呢?按照前一个的逻辑 , s应该还是原来的 a b c 。但是结果并不是 , 真正的结果是:a b d 。这是为什么呢?
首先s的容量是3 , 当我们不截取的时候直接append , 这是容量是不够的 , 所以要扩容到了6 , 扩容一倍 。然后将d添加到扩容后的内存 , 所以这时s1的容量是6 。当我们对s截取前两个元素后 , 那么s的容量仍然是3 , 但是元素只有前两个 , 所以在appen的时候 , d元素把第三个位置占用了 , 然后再把新的给了s1 , 这时 , s1容量也是3 , 值为a b d 。同时 , 由于这个d元素把之前的s的第三个位置占用了 , 所以s也就成了a b d , 也就是最后这个位置元素被覆盖了 。
其实道理很简单 , 如果appen操作中的第一个参数 , 它的容量能够放下后面添加的元素的数量 , 那么第一个参数的值就会改变 , 因为没有扩容 , 如果它的容量不能够放下后面添加的元素 , 那么就会扩容 , 将后面的元素再添加到新扩容的位置 , 这时第一个元素也就是s并不会改变 , 只是把扩容后的给了新的s1 。
今天说这个是希望大家以后遇到了要知道这是为什么 , 因为有时我们做append操作上面两种情况都有可能遇到的 , 尤其是第二种情况 , 大家一定要知道 , 这个s也会改变的 。
【append的用法 append函数的意思及用法】