相关文章推荐
绅士的熊猫  ·  MyBatis-plus报错:Error ...·  1 年前    · 
耍酷的梨子  ·  javascript - ...·  1 年前    · 
Go语言基本语法
3 Go语言容器
3.1 Go语言数组
3.2 Go语言多维数组
3.3 Go语言切片
3.4 使用append()为切片添加元素
3.5 Go语言切片复制
3.6 Go语言从切片中删除元素
3.7 Go语言range关键字
3.8 Go语言多维切片
3.9 Go语言map(映射)
3.10 Go语言遍历map
3.11 map元素的删除和清空
3.12 Go语言map的多键索引
3.13 Go语言sync.Map
3.14 Go语言list(列表)
3.15 Go语言nil:空值/零值
3.16 Go语言make和new关键字的区别及实现原理
Go语言函数 Go语言结构体 Go语言接口 Go语言包(package) Go语言并发 Go语言反射 Go语言文件处理 Go语言编译与工具 a = append(a, 1) // 追加1个元素 a = append(a, 1, 2, 3) // 追加多个元素, 手写解包方式 a = append(a, []int{1,2,3}...) // 追加一个切片, 切片需要解包 不过需要注意的是,在使用 append() 函数为切片动态添加元素时,如果空间不足以容纳足够多的元素,切片就会进行“扩容”,此时新切片的长度会发生改变。
切片在扩容时,容量的扩展规律是按容量的 2 倍数进行扩充,例如 1、2、4、8、16……,代码如下: var numbers []int for i := 0; i < 10; i++ { numbers = append(numbers, i) fmt.Printf("len: %d cap: %d pointer: %p\n", len(numbers), cap(numbers), numbers) 代码输出如下: len: 1  cap: 1 pointer: 0xc0420080e8
len: 2  cap: 2 pointer: 0xc042008150
len: 3  cap: 4 pointer: 0xc04200e320
len: 4  cap: 4 pointer: 0xc04200e320
len: 5  cap: 8 pointer: 0xc04200c200
len: 6  cap: 8 pointer: 0xc04200c200
len: 7  cap: 8 pointer: 0xc04200c200
len: 8  cap: 8 pointer: 0xc04200c200
len: 9  cap: 16 pointer: 0xc042074000
len: 10  cap: 16 pointer: 0xc042074000

代码说明如下: 第 1 行,声明一个整型切片。 第 4 行,循环向 numbers 切片中添加 10 个数。 第 5 行,打印输出切片的长度、容量和指针变化,使用函数 len() 查看切片拥有的元素个数,使用函数 cap() 查看切片的容量情况。 通过查看代码输出,可以发现一个有意思的规律:切片长度 len 并不等于切片的容量 cap。
往一个切片中不断添加元素的过程,类似于公司搬家,公司发展初期,资金紧张,人员很少,所以只需要很小的房间即可容纳所有的员工,随着业务的拓展和收入的增加就需要扩充工位,但是办公地的大小是固定的,无法改变,因此公司只能选择搬家,每次搬家就需要将所有的人员转移到新的办公点。 员工和工位就是切片中的元素。 办公地就是分配好的内存。 搬家就是重新分配内存。 无论搬多少次家,公司名称始终不会变,代表外部使用切片的变量名不会修改。 由于搬家后地址发生变化,因此内存“地址”也会有修改。 除了在切片的尾部追加,我们还可以在切片的开头添加元素:
var a = []int{1,2,3} a = append([]int{0}, a...) // 在开头添加1个元素 a = append([]int{-3,-2,-1}, a...) // 在开头添加1个切片 在切片开头添加元素一般都会导致内存的重新分配,而且会导致已有元素全部被复制 1 次,因此,从切片的开头添加元素的性能要比从尾部追加元素的性能差很多。
因为 append 函数返回新切片的特性,所以切片也支持链式操作,我们可以将多个 append 操作组合起来,实现在切片中间插入元素:
var a []int a = append(a[:i], append([]int{x}, a[i:]...)...) // 在第i个位置插入x a = append(a[:i], append([]int{1,2,3}, a[i:]...)...) // 在第i个位置插入切片 每个添加操作中的第二个 append 调用都会创建一个临时切片,并将 a[i:] 的内容复制到新创建的切片中,然后将临时创建的切片再追加到 a[:i] 中。

关注公众号「 站长严长生 」,在手机上阅读所有教程,随时随地都能学习。本公众号由 C语言中文网站长 亲自运营,长期更新,坚持原创。

微信扫码关注公众号