切片
在Go语言中,切片(Slice)是一种动态数组,是在Go中使用最频繁的数据结构之一。切片比数组更灵活,因为它可以动态增长和缩小。切片是基于数组构建的,但它们的长度可以改变,因此特别适用于需要动态大小的情况。
# 1. 切片的定义和初始化
# 1.1 使用字面量创建切片
可以使用[]Type{}
创建并初始化切片,长度和容量由初始化的元素个数决定。
// 创建并初始化一个整数切片
nums := []int{1, 2, 3, 4, 5}
fmt.Println(nums) // 输出: [1 2 3 4 5]
fmt.Println(len(nums)) // 输出: 5,切片的长度
fmt.Println(cap(nums)) // 输出: 5,切片的容量
1
2
3
4
5
2
3
4
5
# 1.2 使用make
函数创建切片
make
函数可以创建指定长度和容量的切片。
// 创建一个长度为3、容量为5的整数切片
nums := make([]int, 3, 5)
fmt.Println(nums) // 输出: [0 0 0]
fmt.Println(len(nums)) // 输出: 3
fmt.Println(cap(nums)) // 输出: 5
1
2
3
4
5
2
3
4
5
如果只指定长度,容量默认等于长度。
nums := make([]int, 3)
fmt.Println(nums) // 输出: [0 0 0]
fmt.Println(len(nums)) // 输出: 3
fmt.Println(cap(nums)) // 输出: 3
1
2
3
4
2
3
4
# 2. 切片的基本操作
# 2.1 通过索引访问和修改切片元素
nums := []int{1, 2, 3}
fmt.Println(nums[1]) // 输出: 2
nums[1] = 100
fmt.Println(nums) // 输出: [1 100 3]
1
2
3
4
5
2
3
4
5
# 2.2 使用append
添加元素
append
函数可以向切片末尾添加元素,如果容量不足,它会自动扩容。
nums := []int{1, 2, 3}
nums = append(nums, 4, 5)
fmt.Println(nums) // 输出: [1 2 3 4 5]
1
2
3
2
3
# 2.3 使用切片表达式截取切片
可以通过切片[start:end]
的形式创建子切片,start
是起始索引(包含),end
是结束索引(不包含)。
nums := []int{1, 2, 3, 4, 5}
subSlice := nums[1:4]
fmt.Println(subSlice) // 输出: [2 3 4]
1
2
3
2
3
若start
或end
未指定,则默认为0或len(nums)
。
fmt.Println(nums[:3]) // 输出: [1 2 3]
fmt.Println(nums[2:]) // 输出: [3 4 5]
fmt.Println(nums[:]) // 输出: [1 2 3 4 5]
1
2
3
2
3
# 3. 切片的容量和扩容
切片的容量是基于其底层数组的,并且可以动态扩展。使用append
添加元素时,容量不够时会自动扩容,一般是按2倍增长。
nums := []int{1, 2, 3}
fmt.Printf("len=%d cap=%d\n", len(nums), cap(nums)) // len=3 cap=3
nums = append(nums, 4)
fmt.Printf("len=%d cap=%d\n", len(nums), cap(nums)) // len=4 cap=6
1
2
3
4
5
2
3
4
5
# 4. 切片与数组的关系
切片是基于数组实现的,它包含一个指向底层数组的指针、切片的长度以及容量。切片的容量不能小于长度,且切片的修改会影响到原数组内容。
arr := [5]int{1, 2, 3, 4, 5}
nums := arr[1:4] // 创建一个切片,指向数组arr的索引1到3部分
fmt.Println(nums) // 输出: [2 3 4]
nums[0] = 100
fmt.Println(arr) // 输出: [1 100 3 4 5],原数组内容被修改
1
2
3
4
5
6
2
3
4
5
6
# 5. 使用copy
函数复制切片
copy
函数用于将一个切片的元素复制到另一个切片。目标切片的长度不够时,只会复制能容纳的元素数。
src := []int{1, 2, 3}
dest := make([]int, len(src))
copy(dest, src)
fmt.Println(dest) // 输出: [1 2 3]
1
2
3
4
2
3
4
# 6. 切片的遍历
切片可以使用for
循环或for range
语句遍历。
nums := []int{1, 2, 3, 4, 5}
// 使用for循环遍历
for i := 0; i < len(nums); i++ {
fmt.Println(nums[i])
}
// 使用for range遍历
for index, value := range nums {
fmt.Printf("Index: %d, Value: %d\n", index, value)
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 7. 切片的常见应用
# 7.1 动态数组
Go中的切片特别适合用于需要动态变化大小的数组,如收集数据、批量处理等。
var nums []int // 空切片
for i := 1; i <= 5; i++ {
nums = append(nums, i)
}
fmt.Println(nums) // 输出: [1 2 3 4 5]
1
2
3
4
5
2
3
4
5
# 7.2 子切片
切片可以非常方便地生成子切片,用于处理数组或切片的部分数据。
data := []int{10, 20, 30, 40, 50}
subData := data[1:4]
fmt.Println(subData) // 输出: [20 30 40]
1
2
3
2
3
# 7.3 切片作为函数参数
切片可以传递给函数,且切片是引用类型,因此函数内的修改会影响到原切片。
func modifySlice(s []int) {
s[0] = 100
}
func main() {
nums := []int{1, 2, 3}
modifySlice(nums)
fmt.Println(nums) // 输出: [100 2 3],切片内容被修改
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 8. 判断切片是否为空
可以通过检查切片的长度来判断切片是否为空。
var nums []int
if len(nums) == 0 {
fmt.Println("切片是空的")
}
1
2
3
4
2
3
4
# 总结
切片是Go语言中非常强大且灵活的数据结构。它提供了动态数组的功能,并且具备操作底层数组的灵活性。掌握切片的使用方法和特性,可以更高效地处理可变长度的数据。
上次更新: 2024/11/14, 16:29:25