切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型,这个片段可以是整个数组,也可以是由起始和终止索引标识的一些项的子集,需要注意的是,终止索引标识的项不包括在切片内。
Go语言中切片的内部结构包含地址、大小和容量,切片一般用于快速地操作一块数据集合,如果将数据集合比作切糕的话,切片就是你要的“那一块”,切的过程包含从哪里开始(切片的起始位置)及切多大(切片的大小)。
切片的定义
第一种方式:引用一个已定义好的数组 arr[startindex, endindex]
package main
import "fmt"
func main() {
var intArr [5]int = [5]int{11, 22, 33, 44, 55}
fmt.Println("intArr=", intArr)
// 第一种方式,引用一个已定义好的数组
slice := intArr[1:3] // 取intArr数组,下标为1的元素开始,下标为3的元素结束,但不包含下标为3的元素
fmt.Println("slice=", slice)
fmt.Println("slice len=", len(slice))
fmt.Println("slice cap=", cap(slice))
}
![](https://img-blog.csdnimg.cn/img_convert/2b922e2943558c5fdc887fb8649cc1a6.png)
第二种方式:使用make函数 make([]Type, size, cap)
![](https://img-blog.csdnimg.cn/img_convert/0851755a888b8556a3f37ee3a4ffd69c.png)
package main
import "fmt"
func main() {
// 第二种方式,使用make函数
slice := make([]float64, 5, 10)
slice[1] = 22
fmt.Println("slice=", slice)
fmt.Println("slice len=", len(slice))
fmt.Println("slice cap=", cap(slice))
}
![](https://img-blog.csdnimg.cn/img_convert/a0c708a7fd0ee0b7f1126e4da91c7c5e.png)
第三种方式:定义一个切片,直接就指定具体的数组
package main
import "fmt"
func main() {
// 第三种方式,定义一个切片,直接就指定具体的数组
slice := []string{"宋江", "卢俊义", "吴用"}
fmt.Println("slice=", slice)
fmt.Println("slice len=", len(slice))
fmt.Println("slice cap=", cap(slice))
}
![](https://img-blog.csdnimg.cn/img_convert/59c9c0359bfadb9c73cd6833b0b168a4.png)
切片的遍历
for循环
package main
import "fmt"
func main() {
// 切片的遍历,for循环
slice := []string{"宋江", "卢俊义", "吴用"}
for i := 0; i < len(slice); i++ {
fmt.Printf("slice[%v]=%v\n", i, slice[i])
}
}
![](https://img-blog.csdnimg.cn/img_convert/54dc5f1d30f1cd75e0652607081728ee.png)
for range 循环
package main
import "fmt"
func main() {
// 切片的遍历,for range循环
slice := []string{"宋江", "卢俊义", "吴用"}
for i, v := range slice {
fmt.Printf("slice[%v]=%v\n", i, v)
}
}
![](https://img-blog.csdnimg.cn/img_convert/69960a271cb23cac81c211a6cbc98b4c.png)
切片的注意事项和细节
切片初始化时 var slice = arr[startIndex:endIndex]
说明: 从 arr 数组下标为 startIndex,取到 下标为 endIndex 的元素(不含 arr[endIndexl)
切片初始化时,不能越界。范围在 [0-len(arr)] 之间,但是可以动态增长
var slice = arr[0:end] 可以简写 var slice = arr[:end]
var slice = arr[start:len(arr)] 可以简写: var slice = arr[start:]
var slice = arr[0:len(arr)] 可以简写: var slice = arr[:]
cap 是一个内置函数,用于统计切片的容量,即最大可以存放多少个元素
切片定义完后,还不能使用,因为本身是一个空的,需要让其引用到一个数组,或者 make
个空间供切片来使用
切片可以继续切片
用内置函数append,可以对切片进行动态追加到末尾
![](https://img-blog.csdnimg.cn/img_convert/947090d29c9e0b0c5a917fdc5bf523da.png)
slice = append(slice, 66, 77) // 追加一个值
slice = append(slice, slice...) // 追加一个切片
用内置函数copy,可以对切片进行拷贝
![](https://img-blog.csdnimg.cn/img_convert/27de1c763299c7a11e3221c4c88751f5.png)
slice := []int{11, 22, 33, 44, 55}
slice2 := make([]int, 10)
copy(slice2, slice)
fmt.Println("slice2=", slice2) // [11 22 33 44 55 0 0 0 0 0]
切片的引用类型特性
切片是引用类型,字段值会随着函数值改变而改变
package main
import "fmt"
func modify(slice []int) {
slice[2] = 4 // 重写元素值
}
func main() {
var slice = []int{1, 2, 3}
modify(slice)
fmt.Println(slice)
}
上面的例子,slice这个切片值会发生变化为:[1 2 4]