array
数组声明和赋值
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()
均输出数组的容量跟长度,不难发现数组的容量跟长度是一样的。
slice
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的指针思想,宝宝好凌乱啊。
slice的几个内置函数
- cap():slice的最大容量,上例中的 Slice_a和Slice_b的cap()值分别为8和5。正式由于Slice_a容量为8,所以给Slice_b的赋值是有效的
- len():slice的长度,上例已有介绍,Slice_a和Slice_b的len()值分别为3和2
- append():向 slice 里面追加一个或者多个元素,然后返回一个和 slice 一样类型的slice
- copy():函数 copy 从源 slice 的 src 中复制元素到目标 dst ,并且返回复制的元素的个数
make和new操作
make跟new都可以用于内存分配。
- new用于各种类型的内存分配,本质上跟java的new的功能是一样的。new(T)返回了一个指针,指向新分配的类型 T 的零值。
- make只能用于给slice、map和channel类型的内存分配,并且返回一个有初始值(非零)的 T 类型,而不是指针 T。
map
map跟Pythoon的字典概念一样,凌乱了,又开始有python的思想了。关键是不懂python啊,不过没关系,后面我会学它的。
map的格式:
map[keyType] valueType
map的声明:
- 使用map关键字:
var map_variable map[keyType]valueType
- 使用 make 函数,返回一个 map 给 map_variable:
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 是无序的,每次打印出来的 map 都会不一样,它不能通过 index 获取,而必须通过 key 获取
- map 的长度是不固定的,也就是和 slice 一样,也是一种引用类型
- 内置的 len 函数同样适用于 map ,返回 map 拥有的 key 的数量
- map 的值可以很方便的修改,通过 numbers[“one”]=11 可以很容易的把 key 为 one的字典值改为 11
- map 的初始化可以通过 key:val 的方式初始化值,同时 map 内置有判断是否存在 key 的方式;比如:
map_variable := map[string]string{"a": "1", "b": "2", "c": "3"}
- 通过 delete 删除 map 的元素,函数原型
delete(map_variable, key)
有疑问加站长微信联系(非本文作者)