Golang 切片
Golang 切片
定义
-
切片是数组的一个引用, 因此切片是引用类型, 在进行传递时, 遵守引用传递的机制
func main() { //定义一个切片 arr := [...]int{1, 2, 3, 4} //表示截取arr的[1,3) sArr := arr[1:3] fmt.Println(sArr) //2,3 sArr[0] =10 fmt.Println(sArr)//10,3 用于是引用变量, 所以修改切片也会修改数组 fmt.Println(arr)// 1,10,3,4 }
-
切片的使用和数组类似, 遍历切片, 访问切片的元素和求切片长度
len(slice)
都一样 -
切片的长度是可以变化的, 因此切片是一个可以动态变化的数组
-
切片的定义基本语法:
var identifier [] type
func main() { //定义一个切片 arr := [...]int{1, 2, 3, 4} //表示截取arr的[1,3) sArr := arr[1:3] fmt.Println(sArr) //2 ,3 }
-
slice
底层, 其实是一个结构体type slice struct{ p *[len]int len int //切片长度 cap int //切片容量 }
创建切片
使用切片时, 必须初始化
var slice []int //slice未初始化 [], len == 0
fmt.Println(slice)
slice[0] = 20// len == 0 panic
fmt.Println(slice)
方式一: 截取数组
func main() {
arr := [4]int{1,2,3,4}
slice1 := arr[0:2] // 截取[0,2)
fmt.Println(slice1)
}
slice
的指针指向左闭区间, slice
修改值, 外部数组值同时修改
方式二: make
- 指定切片的长度和容量,
capacity >= length
- 如果没有给切片的元素赋值, 就会使用默认值
- 通过
make
创建的切片对应的数组是由make
底层维护, 对外不可见, 只能通过slice
访问各个元素
func main() {
//slice2 := make([]int, 3)len 3,缺省cap, 默认cap == len
slice2 := make([]int, 3,10)//len 3 , cap 10, cap >= len
fmt.Printf("slice2 %v, capacity %v, len %v",slice2,cap(slice2),len(slice2))
}
没有一个变量指向数组, 只能通过slice
访问内存空间
方式三: slice[]{}
类似于make(type, len)
, 默认cap == len
func main() {
var str []string = []string{}//等价 var str = []string{}
strings := []string{"tom","Jack","Lucy"}//区别于数组arr := [3]int{1,2,3}
fmt.Printf("strings %v, len %v,cap %v",strings,len(strings),cap(strings))
}
遍历切片
方式一: 普通for循环
func main() {
slice := []string{"a","b","c","d"}
for i := 0; i < len(slice); i++ {
fmt.Printf("%s",slice[i])
}
}
方式二: for - range
func main() {
slice := []string{1: `world`, 0: `hello`}
for idx, val := range slice {
fmt.Printf("%d, %s \n", idx, val)
}
}
注意事项
-
arr[start : end]
简写func main() { arr := [4]int{1, 2, 3, 4} slice := arr[:2] //如果从0开始,等价于 arr[0:2] fmt.Println(slice) slice = arr[1:] //如果到len(arr),等价于 arr[1:len(arr)] fmt.Println(slice) slice = arr[:]//如果从0到len(arr),等价于 arr[0:len(arr)] fmt.Println(slice) }
-
cap
是一个内置函数, 用于统计切片的容量, 即最大可以存放多少个元素 -
切片定义完后, 还不能使用, 因为本身是一个空的, 需要让其引用到一个数组, 或者
make
一个空间供切片使用 -
切片可以继续切片, 用于是引用类型, slice2改变slice1和数组也会改变
func main() { arr := [4]int{1, 2, 3, 4} slice1 :=arr[:] fmt.Println(slice1) //切片可以继续切片 slice2 := slice1[:3] fmt.Println(slice2) ------------------------- arr := [3]int{100,200,300} slice1 := arr[:] slice2 := slice1[:] fmt.Println(slice1,slice2) slice2[0] = 400 fmt.Println(slice1,slice2) }
-
用
append
内置函数, 可以对切片进行动态追加, 通过make
返回func main() { slice := []int{100,200,300} fmt.Println(slice) //append返回一个新的切片 slice = append(slice, 400, 500) fmt.Println(slice) ----------------------- slice1 := []int{100, 200, 300} slice2 := []int{400, 500} //追加一个切片到slice slice1 = append(slice1, slice2...) fmt.Println(slice1) }
-
切片使用
copy
内置函数完成拷贝, 如果slice2的长度小于slice1同样会执行func main() { slice1 := []int{100,200,300} slice2 := make([]int,5) fmt.Println(slice2) //将slice1拷贝到slice2 copy(slice2,slice1 ) fmt.Println(slice2) }