数组、切片和map
数组
var 数组名[数组大小]数据类型 var a [5]int
4种初始化方式
1 | var numsArrays01 [3]int = [3]int {1,2,3} |
for-range遍历
1 | func traverse(){ |
第一个返回值index是数组的下标第,二个value是该下标位置的值。
他们都是仅在 for循环内部可见的局部变量。
遍历数组元素的时候,如果不想使用下标index,可以直接把下标index标为下划线。
index和value的名称不是固定的.可以z自行指定。
注意
var arr []int
是一个slice切片- 数组创建之后有默认值
- Go的数组属值类型,在默认情况下是值传递,因此会进行值拷贝。数组间不会相互影响如想在其它函数中,去修改原来的数组,可以使用引用传递(指针方式)
- 长度是数组的一部分,在传递函数参数时,需要考虑数组的长度。
案例
1 | //要求:随机生成五个数,并将其反转打印 |
切片
- 切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制。
- 切片的使用和数组类似,遍历切片、访问切片的元素和求切片长度len(slice)都一样。
- 切片的长度是可以变化的,因此切片是一个可以动态变化数组。
- 切片定义的基本语法:
var变量名[类型]
比如:var a []int
1 | func length(){ |
内存布局
slice的确是一个引用类型,容量是动态变化的
slice从底层来说,其实就是一个数据结构(struct结构体)
1
2
3
4
5type slice struct {
ptr *[2]int
len int
cap int
)
使用方式
定义一个切片,然后让切片去引用一个已经创建好的数组。
第二种方式:通过make来创建切片.
基本语法:var切片名[]type = make([], len,[cap])
参数说明: type:就是数据类型len :大小cap:指定切片容量1
var slice []float= make([]float64, 5, 10)
定义一个切片,直接就指定具体数组,使用原理类似make的方式。
1
var slice []sting = []string{"tom","jack","mary"}
方式一和方式2的区别:
方式1是直接引用数组,这个数组是事先存在的,程序员是可见的。
方式2是通过make来创建切片,make也会创建一个数组,是由切片在底层进行维护,程序员是看不见的。
切片和数组的变量方式相同
注意
切片初始化时
var slice = arr[startlndex:endIndex]
说明:从arr数组下标为startIndex
,取到下标为endIndex
的元素(不含arr[endIndex])
切片初始化时,仍然不能越界。范围在[O-len(arr)]之间,但是可以动态增长.1
2
3
4
5
6
7
8
9
10
11var 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内置函数,可以对切片进行动态追加
切片append操作的底层原理分析:
- 切片append操作的本质就是对数组扩容
- go底层会创建一下新的数组newArr(安装扩容后大小)
- 将slice原来包含的元素拷贝到新的数组newArr
4) slice重新引用到newArr
5) 注意newArr是在底层来维护的,程序员不可见.使用内置函数
copy
完成拷贝1
copy(slice,a) //把a拷贝到slice
string和slice
string底层是一个byte数组,因此string也可以进行切片处理
1 | str := "helloworld" |
string是不可变的,也就说不能通过str[0]= 2
方式来修改字符串
如果需要修改字符串,可以先将string -> []byte
/或者[]rune ->修改→重写转成string.
1 | arr1 :=[ ]byte(str) |
二维数组
1 | var arr [2][3]int[][] |
map
var map变量名 map[keytype]valuetype
1 | func createMap(){ |
- map在使用前一定要make
- map的key是不能重复,如果重复了,则以最后这个key-value为准
- map的 value是可以相同的.
- map的 key-value是无序
操作
增加和更新: map[“key”]=value
删除 delete(map.”key),
全部删除可以直接创建一个新的map
查找
1
2
3
4val,ok := a["1"]
if ok {
fmt.println(val)
}遍历
1
2
3
4
5
6
7
8
9func tarverse(){
a := make(map[string]string)
a["1"] = "1"
a["2"] = "2"
a["3"] = "3"
for k,v := range a {
fmt.Println(k,v)
}
}
map排序
1 | func sortMap(){ |
使用切片辅助排序
细节
- map是引用类型,遵守引用类型传递的机制,在一个函数接收map,修改后,会直接修改原来的map
- map的容量达到后,再想map增加元素,会自动扩容,并不会发生panic,也就是说map能动态的增长键值对(key-value)
- map的value也经常使用struct类型,更适合管理复杂的数据