go语言中的切片,你真的了解吗?
0 前言
切片 slice 是 golang 中一个非常经典的数据结构,其定位可以类比于其他编程语言中的数组. 本文介绍的内容会分为 slice 的使用教程、问题讲解以及源码解析,走读的源码为 go v1.19.
1 几个问题首先呢,我觉得使用 go 的朋友对于切片这个数据结构不会感到陌生,一些基本的概念和用法应该是可以做到了然于心的. 下面我先抛出一轮问题,大家可以思考并给出自己的答案,然后带着问题进入本文后半段的学习. 在第 2 章中,我们会进行原理补充,把问题涉及的拼图碎片一块块集齐;最后在第 3 章中,我们会正面给出第 1 章中所有问题的答案.
下面,就正式开启灵魂拷问环节:
1.1 问题1
- • 初始化切片 s 长度和容量均为 10
- • 在 s 的基础上追加 append 一个元素
请问经过上述操作后,切片s 的内容、长度以及容量分别是什么?
func Test_slice(t *testing.T){
s := make([]int,10)
s = append(s,10)
t.Logf("s: %v, len of s: %d, cap of s: %d",s,len(s),cap(s))
}
1.2 问题2
- • 初始化切片 s 长度为 0,容量为 10
- • 在 s 的基础上追加 append 一个元素
请问经过上述操作后,切片s 的内容、长度以及容量分别是什么?
func Test_slice(t *testing.T){
s := make([]int,0,10)
s = append(s,10)
t.Logf("s: %v, len of s: %d, cap of s: %d",s,len(s),cap(s))
}
1.3 问题3
- • 初始化切片 s 长度为 10,容量为 11
- • 在 s 的基础上追加 append 一个元素
请问经过上述操作后,切片s 的内容、长度以及容量分别是什么?
func Test_slice(t *testing.T){
s := make([]int,10,11)
s = append(s,10)
t.Logf("s: %v, len of s: %d, cap of s: %d",s,len(s),cap(s))
}
1.4 问题4
- • 初始化切片 s 长度为 10,容量为 12
- • 截取切片 s index = 8 往后的内容赋给 s1
求问 s1 的内容、长度以及容量分别是什么?
func Test_slice(t *testing.T){
s := make([]int,10,12)
s1 := s[8:]
t.Logf("s1: %v, len of s1: %d, cap of s1: %d",s1,len(s1),cap(s1))
}
1.5 问题5
- • 初始化切片 s 长度为 10,容量为 12
- • 截取切片 s index 为 [8,9) 范围内的元素赋给切片 s1
求问 s1 的内容、长度以及容量分别是什么?
func Test_slice(t *testing.T){
s := make([]int,10,12)
s1 := s[8:9]
t.Logf("s1: %v, len of s1: %d, cap of s1: %d",s1,len(s1),cap(s1))
}
1.6 问题6
- • 初始化切片 s 长度为 10,容量为 12
- • 截取切片 s index = 8 往后的内容赋给 s1
- • 修改 s1[0] 的值
请问这个修改是否会影响到 s? 此时,s 的内容是什么?
func Test_slice(t *testing.T){
s := make([]int,10,12)
s1 := s[8:]
s1[0] = -1
t.Logf("s: %v",s)
}
1.7 问题7
- • 初始化切片 s 长度为 10,容量为 12
请问,访问 s[10] 是否会越界?
func Test_slice(t *testing.T){
s := make([]int,10,12)
v := s[10]
// 求问,此时数组访问是否会越界
}
1.8 问题8
- • 初始化切片 s 长度为 10,容量为 12
- • 截取 s 中 index = 8 后面的内容赋给 s1
- • 在 s1 的基础上追加 []int{10,11,12} 3 个元素
请问,经过上述操作时候,访问 s[10] 是否会越界?
func Test_slice(t *testing.T){
s := make([]int,10,12)
s1 := s[8:]
s1 = append(s1,[]int{10,11,12}...)
v := s[10]
// ...
// 求问,此时数组访问是否会越界
}
1.9 问题9
- • 初始化切片 s 长度为 10,容量为 12
- • 截取切片 s index = 8 往后的内容赋给 s1
- • 在方法 changeSlice 中,对 s1[0] 进行修改
求问,经过上述操作之后,s 的内容是什么?
func Test_slice(t *testing.T){
s := make([]int,10,12)
s1 := s[8:]
changeSlice(s1)
t.Logf("s: %v",s)
}
func changeSlice(s1 []int){
s1[0] = -1
}
1.10 问题10
- • 初始化切片 s 长度为 10,容量为 12
- • 截取切片 s index = 8 往后的内容赋给 s1
- • 在方法 changeSlice 中,对 s1 进行 apend 追加操作
请问,经过上述操作后,s 以及 s1 的内容、长度和容量分别是什么?
func Test_slice(t *testing.T){
s := make([]int,10,12)
s1 := s[8:]
changeSlice(s1)
t.Logf("s: %v, len of s: %d, cap of s: %d",s, len(s), cap(s))
t.Logf("s1: %v, len of s1: %d, cap of s1: %d",s1, len(s1), cap(s1))
}
func changeSlice(s1 []int){
s1 = append(s1, 10)
}
1.11 问题11
- • 初始化切片 s,内容为 []int{0,1,2,3,4}
- • 截取 s 中 index = 2 前面的内容(不含s[2]),并在此基础上追加 index = 3 后面的内容
请问,经过上述操作后,s 的内容、长度和内容分别是什么?此时访问 s[4] 是否会越界?
func Test_slice(t *testing.T){
s := []int{0,1,2,3,4}
s = append(s[:2],s[3:]...)
t.Logf("s: %v, len: %d, cap: %d", s, len(s), cap(s))
v := s[4]
// 是否会数组访问越界
}
1.12 问题12
- • 初始化切片 s 长度和容量均为 512
- • 在 s 的基础上追加 append 一个元素
请问经过上述操作后,切片s 的内容、长度以及容量分别是什么?
func Test_slice(t *testing.T){
s := make([]int,512)
s = append(s,1)
t.Logf("len of s: %d, cap of s: %d",len(s),cap(s))
}