切片拥有自己的长度和容量,
我们可以通过使用内置的len()函数求长度,使用内置的cap()函数求切片的容量
切片在python是很常见的,而且很简单,但是在Golang中就不是那么的好玩了
切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。非常灵活,支持自动扩容。
切片属于引用类型,它的内部结构包含地址、长度和容量。切片一般用于快速地操作一块数据集合
问
1.切片的定义
2.切片初始化
3.由数组得到切片
4.make()函数构造切片
5.append 为切片追加元素
6.copy元素
7.删除元素
切片的定义
var name []T
name表示变量名
T表示切片中的元素类型
切片类型的写法是 []T , T 是切片元素的类型。和数组不同的是,切片类型并没有给定固定的长度。
// 定义切片
var s []int // 定义一个存放int类型元素的切片
var s2 []string // 定义一个存放 string类型元素的切片
fmt.Println(s, s2)
fmt.Println(s == nil)
fmt.Println(s2 == nil)
// nil 相当于空的意思
初始化
s = []int{1, 2, 3}
s2 = []string{"黄河", "张江高科", "平顶山"}
s3 := []int{1,2,3}
fmt.Println(s, s2)
切片的长度和容量,切片的长度就是它元素的个数,
(切片的容量底层数组从切片的第一个元素到最后一个元素的数量) 这句最后去证实一下
切片是引用类型,都指向底层的一个数组
len(s3),cap(s3)
由数组得到切片
切片,基于一个数组的切割,左包含右不包含(左闭右开)
a1 := [...]int{1, 3, 5, 7, 9, 11, 13}
s3 := a1[0:4] //1,3,5,7 切片,基于一个数组的切割,左包含右不包含(左闭右开)
fmt.Println(s3)
s4 := a1[1:6] //3, 5, 7, 9, 11, 13
fmt.Println(s4)
s5 := a1[:4]
s6 := a1[3:] // [3:len(a1)]
s7 := a1[:] // [3:len(a1)]
fmt.Println(s5, s6, s7)
切片的容量是指底层数组的容量
make 构造切片
使用make()函数构造切片
格式 make([]T, size, cap)
T:切片的元素类型
size:切片中元素的数量
cap:切片的容量
// 表示长度是5,容量是10
s1 := make([]int, 5, 10)
fmt.Printf("s1=%v,len(s1)=%d, cap(s1)=%d\n", s1, len(s1), cap(s1))
// 切片的赋值,切片是引用类型,(切片是不保存值的,值都是底层数组保存的)
s3 := []int{1, 3, 5}
s4 := s3 // s3和s4 都指向了同一个底层数组,如果改变了其中的值,对应的s3,s4的值也会改变的
fmt.Println(s4)
s3[0] = 1000
fmt.Println(s3, s4)
// 切片的遍历
// 1.索引遍历
for i := 0; i < len(s3); i++ {
fmt.Println(s3[i])
}
// 2 for range循环
for index, value := range s3 {
fmt.Println(index, value)
}
1.(重点)
切片的本质,就是一个框,框住了一块连续的内存,只能保存 相同类型的
属于引用类型 真正的数据都是保存在底层数组里的
2.切片不能直接比较
切片之间是不能比较的,我们不能直接使用 == 操作符来判断两个切片是否含有全部相等元素,
切片唯一合法的比较操作是和 nil 比较。
一个nil 值的切片并没有底层数组,一个nil 值的切片的长度,和容量都是0,
但是我们不能说一个长度和容量都是0 的切片一定是 nil
var s1 []int
s2 := []int{}
s3 := make([]int,0)
所以要判断一个切片 是否是空,要用len(s) == 0 来判断,不应该使用,s == nil来判断
append 为切片追加元素
var stu = []int{}
fmt.Println(stu)
fmt.Printf("%T\n", stu)
s1 := []string{"北京", "上海", "皇甫村"}
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
s1[3] = "广州" index out of range
错误写法,会导致编译错误,索引越界
调用内置append 函数必须用原来的切片变量接收返回值
s1 = append(s1, "郑州")
在尾部追加
append追加元素,原来的底层数组放不下的时候,
Go底层就会把底层数组换一个,必须用(原来的)变量接收append的返回值
fmt.Println(s1)
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
ss := []string{"新乡", "卫辉", "卫河"}
s1 = append(s1, ss...) ... 表示拆开,也就是说 把新乡,卫辉,卫河 单独拿出来
fmt.Println(s1, len(s1), cap(s1))
千万要注意容量变化
copy
a1 := []int{1, 3, 5}
a2 := a1 // 切片是引用类型,这里我们可以认为是a1,a2,同时指向同一片内存地址
var a3 []int //nil (没有理解)
var a3 = make([]int, 3, 3) //长度3,容量3
copy(a3, a1) //copy 就是浅copy
fmt.Println(a1, a2, a3)
a1[0] = 100
fmt.Println(a1, a2, a3)
// 从切片中删除元素
a := []int{30, 31, 32, 33, 34, 35, 36, 37}
// 要删除索引为2的元素
a = append(a[:2], a[3:]...)
fmt.Println(len(a), cap(a), a) //[30 31 33 34 35 36 37]
有疑问加站长微信联系(非本文作者)