切片的简介
概念
切片是一个引用类型,可以创建"字符串"切片,可以创建"整型"切片等
切片和数组的区别( !!!!重点)
- 切片和数组相似,它们都是保存相同数组类型元素的容器,但是切片的元素个数是可变的, 数组不可变
- 切片不需要明确指定元素的个数
创建切片方法
var s []int //创建int类型切片 var s []string //创建string类型切片
切片的内部实现
切片是一个很小的对象,它对底层的数组(内部是通过数组保存数据的)进行了抽象,并提供相关的操作方法;
切片是有三个字段的数据结构,这些数据结构包含Go语言需要操作底层数组的元数据
这3个字段分别是: 指向底层数组的指针、切片访问的元素的个数(即长度)、切片允许增长到的元素个数
切片的创建和初始化(字面创建)And 对比
一、字符串类型 和 字符串类型切片 和 字符串类型数组对比
//创建 "字符串" 数据类型 myStr1 := "hahaha" fmt.Println(myStr1) fmt.Printf("%T ",myStr1) //结果: hahaha #字符串打印结果 string #字符串 数据类型 --------------------------------------------------------- //创建 "字符串"类型的切片 myStr2 := []string{"zhangsan", "list", "wangwu"} fmt.Println(myStr2) fmt.Printf("%T ",myStr2) //结果: [zhangsan list wangwu] #字符串类型切片打印的结果 []string #字符串类型的切片 --------------------------------------------------------- //创建"字符串"类型的数组 myStr3 := [3]string{"zhangsan","lisi","wangwu"} fmt.Println(myStr3) fmt.Printf("%T",myStr3) //结果: [zhangsan lisi wangwu] [3]string #字符串类型的数组
可以看到,字符串 数组和切片的区别就是 切片不需要声明 长度
二、int数据类型 和 int类型切片 和 int类型的数组对比
//创建int类型的 数据类型 myInt03 := 28 fmt.Println(myInt03) fmt.Printf("%T",myInt03) //结果: 28 int #数据类型为int ------------------------------------------------------- //创建int类型的 数组 myInt01 := [3]int{1,2,3} #需要指定长度 fmt.Println(myInt01) fmt.Printf("%T ",myInt01) //结果: [1 2 3] [3]int #是int类型的数组 ------------------------------------------------------ //创建int类型的 切片 myInt := []int{1,2,3} #不需要指定长度 fmt.Println(myInt) fmt.Printf("%T",myInt) //结果: [1 2 3] []int #打印出来的数据类型里 不带长度标识
可以看到 int类型的数组和切片的区别就是 切片不需要声明长度
切片的创建和使用
切片常用的操作和含义
通过make()函数声明切片
使用Go语言内置的make()函数创建切片,此时需要传入一个参数来指定切片的长度
// 创建一个整型切片 // 其长度和容量都是 5 个元素 slice := make([]int, 5)
此时只指定的切片的长度,那么切片的长度和容量是相等的,都是5;
也可以分别指定长度和容量
// 创建一个整型切片 // 其长度为 3 个元素,容量为 5 个元素 slice := make([]int, 3, 5)
Go语言不允许容量<长度,会报错
二、声明切片(普通方式)
//声明一个空的切片,未引用任何数组,所以这个切片现在nil,意思就是切片的零 值 var s = []int fmt.Println(s == nil)
//结果: true
2.1上面的结果为什么nil?
因为切片只是对一个数组的引用,切片是不存储任何数据的,数组是存在数组中的;
当切片需要扩容时,就会创建一个合适长度的新数组,以存储更多数据;
当我们用var s []int创建一个切片时,它还没有引用任何数组,所以它的值时nil
下面我们创建一个切片,并引用数组
//创建一个空int类型切片 var s []int //创建一个int类型数组 var arry = [9]int{1,2,3,4,5,6,7,8,9} //引用数组,对其进行切片,截取小标2:4-1的元素 s = arry[2:4] fmt.Println(s) //结果: [3 4]
2.2数组的值被修改, 会不会影响切片的结果
//创建一个空 int类型切片 var s []int //创建一个int类型数组 var arry = [9]int{1,2,3,4,5,6,7,8,9} //窃取数组a的2:4-1元素的值 s = arry[2:4] //对数组a的下标2:4-1元素的值进行修改. arry[2] = 33 arry[3] = 44 //打印切片s fmt.Println(s) //结果: [33 44]
#可以看到,修改完数组的值,切片获取的值 也变了
2.3切片初始化