Go语言的数组和切片
数组
数组简介
。。。
数据的遍历
常规遍历
hroes := [...]string{"宋江", "吴用", "胡军一"}
// 常规遍历
for i := 0; i < len(hroes); i++ {
fmt.Println(hroes[i])
}
for-range结构遍历
for-range是go语言独有的结构,可以直接获取数组的下标和值
语法如下:
hroes := [...]string{"宋江", "吴用", "胡军一"}
// for range 遍历
for index, value := range hroes{ // index是下标,value是值,这个两个变量名称可以自定义
fmt.Println(index)
fmt.Println(value)
}
切片(Slice)
已经存在数组了为什么还需要使用切片?切片和数组有什么区别?
- 数组的长度是固定的,使用前有时无法预估实际大小,如果分配小了后期进行扩容复杂,分配大了会造成空间浪费
- 数组是值类型的,默认情况是值传递,因此会进行值拷贝,所以如果在其他函数中修改数组,需要使用指针(引用传递)
- 切片长度是可变的,是一个动态变化的数组
- 切片是数组的一个引用,是引用类型,在进行传递时,遵守引用传递机制
切片的使用
切片的创建方式
-
定义一个切片,让该切片去引用创建好的数组
var intArr [5]int = [...]int{1, 22, 223, 341, 32} slice := intArr[1:3] fmt.Println(intArr) fmt.Println(slice) -
通过make创建切片
基本语法:var 切片名 []type = make([]type, len, [cap])
参数说明: type: 就是数据类型 len : 大小 cap :指定切片容量,可选, 如果你分配了 cap,则要求 cap>=len.
var makeSlice []int = make([]int, 5, 10) makeSlice[1] = 10 makeSlice[2]= 25 fmt.Println(makeSlice)make创建切片可以指定切片的大小和容量
如果没有赋值会默认值
通过make创建的切片对应的数组是由make底层维护,对外不可见,只能通过slice去访问各个元素,第一种方式对外是可见的
切片和数组对比
数组:
数组固定长度 数组长度是数组类型的一部分,所以[3]int和[4]int是两种不同的数组类型 数组需要指定大小,不指定也会根据处初始化对的自动推算出大小,不可改变 数组是通过值传递的
切片:
切片可以改变长度 切片是轻量级的数据结构,三个属性,指针,长度,容量 不需要指定大小 切片是地址传递(引用传递) 可以通过数组来初始化,也可以通过内置函数make()来初始化,初始化的时候len=cap,然后进行扩容
在传递时候的区别:
- 数组是值传递
- 切片是地址传递
func main() {
arr1 := [3]int{1, 2, 3}
arr2 := []int{1, 2, 3}
changeArr(arr1)
changeSlice(arr2)
fmt.Printf("%T\n", arr1)
fmt.Printf("%T\n", arr2)
fmt.Println(arr1)
fmt.Println(arr2)
}
func changeArr(arr [3]int) {
arr[0] = 9
}
func changeSlice(arr []int) {
arr[0] = 9
}
结果为
[1 2 3]
[9 2 3]