切片
定义
切片是go语言的动态数组,可以按需自动增长和缩小。
内部实现
切片是对数组的抽象,并提供了相关的操作方法。
因为切片的底层是数组,所以切片的底层内存也是连续的,也就有快速获得索引,迭代和垃圾回收优化的好处。
切片有三个字段。分别是指向底层数组的指针、切片的长度、切片的容量。
在64位架构的机器上,一个切片需要24字节的内存,三个字段各需要8字节。
切片的长度是能够访问到的范围。
切片的容量是底层数组的大小。
例如某切片的长度为3,容量为5,那么底层数组的大小就是5,能访问的索引范围为0-2。
如果访问其他索引,代码在编译时会报访问越界错误。
底层数组剩下的2个位置也可以通过操作合并到切片。
创建和初始化
使用内置的make函数创建切片,注意切片长度不能大于容量。
// 创建一个字符串切片,长度和容量都是5
slice := make([]string,5)
// 创建一个整形切片,长度为3,容量为5
slice := make([]int,3,5)
使用切片字面量创建切片,和创建数组类似,只是不需要指定**[]运算符**里的值。
切片的长度和容量会基于初始化时提供的元素的个数确定。
// 使用切片字面量创建一个整型切片,长度和容量都是5
slice := []int{
10,20,30,40,50}
// 使用空字符串初始化第100个元素,这个切片长度和容量都是100
slice := []string{
99:""}
注意,[]运算符里写了数字就是声明了一个数组,没写就是切片。
// 创建有3个元素的整型数组
array := [3]int{
10,20,30}
// 创建长度和容量都是3的整形切片
array := []int{
10,20,30}
nil和空切片
**nil切片:**用于描述一个不存在的切片
// 创建nil整型切片
var slice []int
使用场景:
例如函数要求返回一个切片,但是发生了异常,可以返回一个nil切片表示。
——
**空切片:**用于描述空集合
// 使用make创建空的整型切片
slice := make([]int,0)
// 使用切片字面量创建空的整型切片
slice := []int{
}
空切片常用来表示空集合。
——
nil切片和空切片的区别:
nil切片没有地址,空切片有地址。
func main() {
var s1 []int
s2 := []int{
}
fmt.Printf("s1=%p\n",s1)
fmt.Printf("s2=%p",s2)
}
使用切片
// 创建一个整型切片
slice := []int{
10,20,30,40,50}
// 改变索引为1的元素的值
slice[1] = 25
// 使用切片创建一个新切片,长度为2(索引1和索引2,符合前闭后开原则),容量为4(由原底层数组决定的),实现原理如图
newslice := slice[1: