go的数组声明跟C语言很相似,除了数组类型放在变量名后面【这点跟变量的声明一样】。
数组的定义格式:
//一维数组
var 数组名[n] 数组类型 //需要注意的是:'[n]'可以写成'[...]',go会自动根据元素个数来计算长度,
//我猜应该是编译的时候计算的吧
//二维数组
var 数组名[2][n]int{[n]数组类型{..},[n]数组类型{}}
数组的声明和赋值:
//一维数组
var ar = [5]byte {'a', 'b', 'c', 'd', 'e'}
//也可以
ar := [5]byte {'a', 'b', 'c', 'd', 'e'}//注意这个只能是函数内部定义,也就是局部变量
//二维数组
var arr = [2][4]int{ [4]int{1, 2, 3}, [4]int{4, 5, 6} }
//可以省略{}中的[4]int
var arr = [2][4]int{ {1, 2, 3}, {4, 5, 6} }
Go中,函数cap()
和len()
均输出数组的容量跟长度,不难发现数组的容量跟长度是一样的。
Go的数组用的是C的思想,那么slice则用的是java的思想。slice在内存中的本质其实也是数组,体现为连续的内存块。但是它与数组又有不同,数组一旦定义好了,它的大小也就固定了;而slice的大小是可以变化的,但又不是java中真正意义上的动态数组,而是数组的引用,是一个引用类型。
slice的声明跟数组的声明一样,只是不需要长度。
slice的声明:
var fslice []int//注意这里没有长度,所以不要把它认为是数组哦
//同样也可以
slice := []int{1,2,3}
sliced的声明和赋值:
var ar = []byte {'a', 'b', 'c', 'd', 'e'}
//也可以
ar := []byte {'a', 'b', 'c', 'd', 'e'}//注意这个只能是函数内部定义,也就是局部变量
我们也可以从一个数组或者一个已经存在的slice中再次声明。slice 通过 array[i:j] 来获取,其中 i是数组的开始位置, j 是结束位置,但不包含 array[j] ,它的长度是 j-i
//声明一个数组
var Array_ori = [11]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}
//声明两个slice
var Slice_a,Slice_b[]byte
//Slice_a指向数组Array_ori,第2个元素`Array_ori[2-1]`开始,第5个元素`Array_ori[5-1]`结束
slice_a = Array_ori[2:5]
//slice1指向数组Slice_a,第3个元素`Slice_a[3-1]`开始,第5个元素`Slice_a[5-1]`结束
slice_b = Slice_a[3:5]//先自己想下会输出什么
根据上图,不难推导出Array_ori, slice_a, slice_b的内容输出如下:
Array_ori:[a b c d e f g h i j k]
slice_a:[c d e]
slice_b:[f g]
是不是对slice有种似曾相识的感觉,没错,感觉跟C的指针很像,一开始学的时候感觉有java的动态数组的思想,这会又有C的指针思想,宝宝好凌乱啊。
make跟new都可以用于内存分配。
map跟Pythoon的字典概念一样,凌乱了,又开始有python的思想了。关键是不懂python啊,不过没关系,后面我会学它的。
map[keyType] valueType
map的声明:
var map_variable map[keyType]valueType
map_variable = make(map[keyType]valueType)
map的声明和赋值
var numbers map[string] int
// 另一种 map 的声明方式
numbers := make(map[string]int)
numbers["one"] = 1 //赋值 key是“one”,值是1
numbers["ten"] = 10 //赋值
numbers["three"] = 3
fmt.Println("第三个数字是: ", numbers["three"]) // 读取数据打印出来如:第三个数字是: 3
map注意事项:
map_variable := map[string]string{"a": "1", "b": "2", "c": "3"}
delete(map_variable, key)