切片 Slice 在 go 语言中是单独的类型 (指向底层的数组), 不同于 python(对可迭代对象操作的工具), 注意区分数组和 slice 的区别
定义一个空 slice, 格式 var s []int, 这种既没有长度也没有元素赋值的类型 (相比叫 array)
数组的基本操作如下 , 类似与 python 中列表切片的操作, 详见实例
- package main
- import "fmt"
- func main() {
- var s1 []int // 这样就是一个 slice 类型, 既没有长度也没有元素赋值
- a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} // 这是一个数组
- s2 := a[5:10] // 切片, 索引 5 到 10 的元素, 不包含索引为 10
- s3 := a[:3] // 切片, 索引 1-3 的元素, 不包含索引 3
- s4 := a[6:] // 切片, 第 6 个索引到最后一个索引的元素
- s5 := a[:] // 切片, 复制一个数组
- fmt.Println(s1)
- fmt.Println(a)
- fmt.Println(s2) // 数组的切片, 类似 python
- fmt.Println(s3)
- fmt.Println(s4)
- fmt.Println(s5)
- }
- /* 输出
- s1---> []
- a---> [0 0 0 0 0 0 0 0 0 0]
- s2---> [6 7 8 9 10]
- s3---> [1 2 3]
- s4---> [7 8 9 10]
- s5---> [1 2 3 4 5 6 7 8 9 10]
- */
使用 make 初始化一个 slice 类型, 包含三个参数
切片类型 []int
初始长度 len
容量 cap
- package main
- import "fmt"
- func main() {
- s1 := make([]int, 3, 10) // 使用 make 初始化一个 slice, 包含三个参数:切片类型初始长度容量
- fmt.Println(len(s1), cap(s1)) // 输出长度, 容量
- fmt.Println(s1)
- }
- /* 输出:
- len(s1)--->3
- cap(s1)--->10
- s1---> [0 0 0] // 可变数组
- */
Reslice , 在原 slice 基础上再次切片, slice 一个数组时, 不仅取出了 len, 同时容量也会得到相应的切片.
示例
- //Reslice, 在 slice 基础上再次 slice.
- package main
- import "fmt"
- func main() {
- a := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'k', 'm'} // 定义一个数组, 元素为 byte 类型
- sa := a[3:5] // slice 切片, 取索引三到五, 不包含索引 5
- sb := sa[1:3]
- fmt.Println(string(sa))
- fmt.Println(len(sa), cap(sa))
- fmt.Println(string(sb))
- fmt.Println(len(sb), cap(sb))
- }
- /* 输出
- sting(sa)---> de
- len(sa)---> 2
- cap(sa)---> 6
- string(sb)---> ef
- len(sb)---> 2
- cap(sb)---> 5
- */
Append, 类似 python 中 list 类型, 使用 append, 从数组尾部追加元素
可以将一个 slice 追加在另一个 slice 尾部
如果最终长度未超过追加到 slice 的容量, 则返回原始 slice
如果超过追加的 slice 的容量则将重新分配数组并拷贝原始数据
- package main
- import "fmt"
- func main() {
- s1 := make([]int, 3, 8) // 初始化 slice, 长度位 3, 容量为 8
- fmt.Printf("%p\n", s1) // 输出 s1 的内存地址
- fmt.Println(s1)
- s1 = append(s1, 1, 2, 3) // 末尾追加三个元素, cap 依然为 8
- fmt.Printf("%p\n", s1) // 原来的 slice
- fmt.Println(s1)
- s1 = append(s1, 1, 2, 3, 4) // 继续追加元素, 超过原 s1 容量, 会重新分配新的内存地址
- fmt.Printf("%p\n", s1) //cap 容量超过 8, 为 9
- fmt.Println(s1)
- }
- /*
- p*s1---> 0xc042070040
- s1---> [0 0 0]
- p*s1s1--> 0xc042070040
- s1---> [0 0 0 1 2 3]
- p*s1---> 0xc04205e080 // 新的内存地址
- s1---> [0 0 0 1 2 3 1 2 3 4]
- */
当两个 slice 同时指向某一个数组时, 改变某一个 slice 索引时, 另一个 slice 索引值及原数组的索引也会改变
- package main
- import "fmt"
- func main() {
- a := []int{1, 2, 3, 4, 5, 6}
- s1 := a[2:5]
- s2 := a[1:3]
- fmt.Println(s1, s2)
- s1[0] = 9
- fmt.Println(s1, s2)
- fmt.Println(a)
- }
- /*
- s1---> [3 4 5]
- s2---> [2 3]
- // 更改 s1 的 slice 索引后, s2 的索引也会改
- s1---> [9 4 5]
- s2---> [2 9]
- a---> [1 2 9 4 5 6]
- */
copy, 格式 copy(s1,s2), 将 s2 拷贝到 s1 数组中, 当 len(s1)> len(s2) 时, 最终将 s2 中的索引
替换掉 s1 的索引, 当 len(s1)<len(s2) 时, s1 的索引值全部被对应 s2 的索引替换
示例
- package main
- import "fmt"
- func main() {
- s1 := []int{1, 2, 3, 4, 5}
- s2 := []int{6, 7, 8}
- copy(s1, s2) // 将 s2 的元素拷贝到 s1,s2
- fmt.Println(s1)
- copy(s2, s1)
- fmt.Println(s2)
- copy(s1, s2[2:3]) // 只拷贝某一切片的索引
- fmt.Println(s1)
- }
- /* 输出
- s1---> [6 7 8 4 5]
- s2---> [1 2 3]
- s1---> [8 2 3 4 5]
- */
来源: https://www.cnblogs.com/failymao/p/9281873.html