Go 语言笔记:切片
切片的概念
切片和数组一样都是序列,但切片是变长的,因此切片声明时一般写作
[]Type
,切片是对数组的引用,也就是说切片会将数组作为其底层的数据结构,可以时数组由某个索引开始到另一个索引终止对一段连续片段。
切片的创建
使用
[]Type
创建切片
go
// 声明整形类型的切片
var nums []int
// 声明空切片
var nums = []int{}
// 初始化一个非空切片
var slice = []int{1, 8}
// 截取数组获得切片
arr := [5]int{10, 20, 30, 40}
var nums = arr[1:2]
fmt.Println(nums) // [20 30]
使用语法 arr[start:end]
是创建一个从数组 arr
索引 start
开始到 end - 1
结束的切片,左开右闭。除此之外,我们也可以使用 make
函数创建 一个切片,格式为 make([]type, size, cap)
go
// 创建一个长度为2,容量为3的整形切片
nums := make([]int, 2, 3)
切片的长度和容量
切片的组成部分为:指针、长度和容量,指针指向切片第一个元素对应的底层数组元素的地址,长度对应切片中元素的个数,容量是从切片的开始位置到底层数据的结束位置,且长度不能超容量。我们可以使用内置的
len
和cap
函数分别获取切片的长度和容量。
go
arr := [5]int{10, 20, 30, 40}
var nums = arr[1:2]
fmt.Println(len(nums)) // 1
fmt.Println(cap(nums)) // 3
切片和数组不同,切片是引用类型,因此其默认值为 nil
go
var nums []int
fmt.Println(nums == nil) // true
但一个切片中的元素为空时,应该判断其长度是否为 0 作为一个空切片的判断依据。切片之间不能直接比较,必须对切片中的每个元素进行比较来判断两个切片是否相等,标准库中针对字节类型的切片([]byte)是否相等提供了 bytes.Equal
函数。
切片的修改
切片本身不拥有任何数据,它只是底层数组的一种表示方式,对切片的任何修改都会反应到底层数据中。
go
arr := [5]int{10, 20, 30, 40}
var nums = arr[1:3]
fmt.Println(arr) // [10 20 30 40]
fmt.Println(nums) // [20 30]
// 修改切片
nums[0] = 50
fmt.Println(arr) // [10 50 30 40]
fmt.Println(nums) // [50 30]
切片追加元素
使用
append
函数可以将新的元素追加到切片上,当新的元素加入到切片之后,会创建一个新的数组,现有数组的元素被复制到这个新的数组中,并返回这个新数组的新切片引用,如果追加后长度超过旧切片的长度时,新切片的容量会变成旧切片容量的两倍。
go
nums := []int{1, 2}
fmt.Println(cap(nums)) // 2
// 追加一个元素 3
nums = append(nums, 3)
fmt.Println(cap(nums)) // 4
// 追加两个元素 4 5
nums = append(nums, 4, 5)
fmt.Println(cap(nums)) // 8
// 追加一个切片 ... 表示解包不能省略
nums = append(nums, []int{6, 7}...)
fmt.Println(cap(nums)) // 8
// 在第一个位置插入一个元素 0
nums = append([]int{0}, nums...)
fmt.Println(cap(nums)) // 8
nums = append(nums, 9)
fmt.Println(cap(nums)) // 16
fmt.Println(nums) // [0 1 2 3 4 5 6 7 9]
获取切片元素
和数组一样,我们也可以使用
for range
循环来获取切片 的索引和索引对应的值
go
nums := []int{1, 2, 3, 4, 5}
for idnex, value := range nums {
fmt.Printf("nums[%d] = %d\n", index, value)
}
多维切片
go
nums := [][]string {{"a", "A"}, {"b", "B"}, {"c", "C"}}
fmt.Println(cap(nums)) // 3
fmt.Println(len(nums)) // 3