定义方式:var arr [n]type,n表示数组的长度,type表示存储元素的类型。定义好后,可以使用arr[0] = 42,这样指定下标来进行数组的读取和赋值。
注意:在go中长度也是类型的一部分,因此[3]int和[5]int是不同类型的。
go中数组不可以改变长度,数组之间的赋值是值的拷贝赋值,即当把一个数组作为一个参数传人函数的时候,传入的其实是数组的备份。arr := [10]int{1,2,5:6},da := [2][4]int{[4]int{1,2,3,4}, [4]int{5,6,7,8} },如果内部的元素和外部的一样,那么声明可以简化,直接忽略内部的类型 ea := [2][4]int{{1,2,3,4},{5,6,7,8}},如果不知道数组的个数,而是按照初始化给定的值,使用 arr := [...]int{1,2,3},用三个"."点号来指定。
slice就是“动态的数组”,传值的时候他也是拷贝赋值,只是他拷贝的是内存地址,是传递指针的。slice总是指向一个底层的array,slice声明也像array一样,只是不需要长度。
声明:var ys []int,slice可以从一个数组或一个已经存在的slice中再次声明,slice通过array[i:j]来获取,其中i为数组的开始位置,j为结束位置,点不包括j,它的长度为j-i,如果不指定i,默认从开头开始,不指定j,则直到数组的最后一位。注意:slice的引用是内存地址,所以当改变其中的元素的值时,其他的所有指向该slice都会改变该值。len()获取slice的长度,cap()获取slice的最大容量,slice的容量为提取数组的开始位置到数组结束位置,即:
则len(s)为3,而cap(s)为8。append(s, 追加的元素),如果没有超过slice的cap值,则会返回原来的slice引用,从而影响到引用同一个数组的其他slice,如果超过了cap值,则会新建一个slice,并返回新slice的引用,此种状态会跟原来的slice脱离引用关系。
copy()函数从源slice的src中复制元素到目标dst,并返回复制元素的个数,如:
sl1 := []int{10, 2, 3}
sl2 := make([]int, 10)
copy(sl2[5:8], sl1[:2])
结果为 0,0,0,0,0,10,2,0,0,0,0
map:
定义方式:map[keyType]valueType,要分别声明键和值的类型,如:map[string]int,map的读取和设置跟slice一样,通过key进行操作,声明可以使用 article := map[string]string{"tech":"the google ....", "music":"或是展翅高飞保持愤怒...."},或者先使用make来创建内存空间,再用下标的形式来赋值,如
article := make(map[string]string),
article["tech"] = "the google ..."
article["music"] = "谁知道我们该去向何处..."
注意:map是无序的,每次打印出来的map值都会不一样。
来判断map是否有相应的下标可以使用:golang, ok := language["go"],通过map[key]可以返回两个值,一个返回相应下标下的值,一个如果指定的下标在map中不存在返回false,存在返回true。
删除指定下标的元素,使用 delete(map, "key")。
在go语句中,只有这三种类型是拷贝内存地址的,slice,map,channel,其他的都是拷贝赋值,len()函数同样可以用来获取map中key的个数。make可以为这三种类型进行内存的分配,同时也只能用在这三种类型上,make初始化了内部的数据结构,填充适当的值,返回初始化后的非零值,new可以用于各种类型的内存分配,new(TYPE)分配了零值填充的TYPE类型的内存空间,并返回其地址。即它返回的是一个内存地址*TYPE类型的值(指针)。
”零值“,并非是空值,也不是都是0,对于integers,floats的”零值“为0,对于布尔值的值为false,对于字符串”零值“为空字符串。pointers, functions, interfaces, slices, maps, channels的“零值”为nil。不能把“零值”当作布尔false来进行判断,如:
var a int
if a {
fmt.Println("true")
} else {
fmt.Println("false")
}
这样是报错的。
有疑问加站长微信联系(非本文作者)