Golang 切片
一、切片的基本介绍
- 切片的英文是 slice
- 切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制。
- 切片的使用和数组类似,遍历切片、访问切片的元素和求切片长度 len(slice)都一样。
- 切片的长度是可以变化的,因此切片是一个可以动态变化数组。
- 切片定义的基本语法:
var 切片名 []类型
比如:var a [] int
示例:
func main() {
var arr = [...]string{"张学友","刘德华","黎明","郭富城","成龙","周星驰"}
slice :=arr[1:3:5]
fmt.Printf("slice容量:%d,长度:%d,值:%v\n",cap(slice),len(slice),slice)
fmt.Printf("slice地址:%p",slice)
}
slice容量:4,长度:2,值:[刘德华 黎明]
slice地址:0xc000084130
二、切片在内存中形式
总结:
从上面可以看到
- slice的确是一个引用类型
- slice 从底层来说,其实就是一个数据结构(struct结构体)
type slice struct {
ptr *[2]int
len int
cap int
}
三、切片的使用
1、切片的定义
- 第一种方式
定义一个切片,然后让切片去引用一个已经创建好的数组,比如前面的案例就是这
样的。
slice :=arr[a:b:c]
a:起始位置
b:截取数据的结束位置 默认到末端)
c:截取后的容量位置 默认到末端)
slice的len = b - a
slice的cap = c - a
底层数组: 为原数组的下标a到下标b(不包括)的所有元素
- 第二种方式:
通过 make 来创建切片
基本语法:var 切片名 []type = make([]type, len, [cap])
参数说明:
type: 就是数据类型
len : 大小
cap :指定切片容量,可选, 如果你分配了 cap,则要求 cap>=len.
func main() {
slice :=make([]int,3,5)
slice[0] = 100
slice[1] = 200
slice[2] = 300
fmt.Printf("slice容量:%d,长度:%d,值:%v\n",cap(slice),len(slice),slice)
fmt.Printf("slice地址:%p\n",slice)
//slice[3] = 400 //runtime error: index out of range 报错
slice = append(slice, 400)
slice = append(slice, 500)
fmt.Printf("slice容量:%d,长度:%d,值:%v\n",cap(slice),len(slice),slice)
fmt.Printf("slice地址:%p\n",slice)
slice = append(slice, 600)
fmt.Printf("slice容量:%d,长度:%d,值:%v\n",cap(slice),len(slice),slice)
fmt.Printf("slice地址:%p",slice)
}
slice容量:5,长度:3,值:[100 200 300]
slice地址:0xc000016120
slice容量:5,长度:5,值:[100 200 300 400 500]
slice地址:0xc000016120
slice容量:10,长度:6,值:[100 200 300 400 500 600]
slice地址:0xc000074000
总结:
(1) 通过 make 方式创建切片可以指定切片的大小和容量
(2) 如果没有给切片的各个元素赋值,那么就会使用默认值[int , float=> 0 string =>”” bool =>
false]
(3) 通过 make 方式创建的切片对应的数组是由 make 底层维护,对外不可见,即只能通过 slice 去
访问各个元素
与第一种方式的区别:
- 第 3 种方式
定义一个切片,直接就指定具体数组,使用原理类似 make 的方式
func main() {
slice :=[]string{"张学友","刘德华","黎明","郭富城","成龙","周星驰"}
fmt.Printf("slice容量:%d,长度:%d,值:%v\n",cap(slice),len(slice),slice)
fmt.Printf("slice地址:%p",slice)
}
slice容量:6,长度:6,值:[张学友 刘德华 黎明 郭富城 成龙 周星驰]
slice地址:0xc000052180
四、切片的遍历
切片的遍历和数组一样,也有两种方式
- for 循环常规方式
- 遍历for-range 结构遍历
func main() {
slice :=[]string{"张学友","刘德华","黎明","郭富城","成龙","周星驰"}
fmt.Println("常规方式")
for i:=0; i<len(slice) ; i++ {
fmt.Printf("%d ===> %v\n",i,slice[i])
}
fmt.Println("结构遍历")
for index,value := range slice{
fmt.Printf("%d ===> %v\n",index,value)
}
}