数组,切片,映射指的就是array,slice和map这三种类型.其中有部分第三章的内容在这里先做个记录.
- 对于中文字符,utf8字符串的处理.可以转换为[]rune.这样可以遍历出完整的字符
而不是字节 - go doc指令的一个扩充,生成web页面查看 godoc -http=:6060访问本地的6060端口即可
- 接下来是第四章的一些记录(基于golang1.7)
数组(array)
Go的数组的定义规范和java类似,是一个长度固定的数据类型,存储的数据必须是类型一致的.
其存储在一段连续的内存区间,所以读取快速.
声明和初始化
声明方法:
这是声明了一个长度为5的int数组.编译器会根据其类型做相应的初始化.比如这里数组里存储的就是int的零值 0.在后续的代码里我们可以对其做赋值操作.当然也可以声明时初始化:
这里就是在声明时初始化.其中长度表示那里的三个点是代表由Go根据初始化时的值自己计算长度.还有一种指定下标的初始化方法:
上面的代码就是声明了一个长度为100的int数组,其中下标为99的元素的值就是99,其他则是默认的0
至于数组的处理则可以通过下标索引操作.比如赋值
长度以及类型一致的数组可以相互赋值
书里还提到了指针数组.
这里声明了一个长度为5的int指针的数组.而通过*
操作符则可以操作指针指向的值
这里还用到了new().这里记下make和new的区别
make:用来初始化map,slice,channel.返回的就是初始化后的对象而不是指针.其会根据类型赋予类型对应的零值
new:这个可以用于任何结构,但是只是声明空间返回指针,内部并不会做初始化.
切片(slice)
切片是建立在数组之上的数据结构,其内部存储了指向底层数组的指针,长度以及容量.
长度是指得当前slice中元素个数(可以通过len()获得),容量则是在创建slice时指定的长度上限(通过cap()可以获得).
声明以及初始化
上面有提到make()创建并初始化slice.具体语法是:
这就是创建了一个长度为3,容量为5的切片.容量参数未设置默认与长度相同(当然容量必须大于等于长度).当然也可以和数组一样通过字面量创建或者基于数组创建
切片的操作和数组其实是一样的,通过下标索引.也可以在切片的基础上再建切片.
不过这里在操作slice的时候实际操作的是底层数组,因为slice是基于底层数组的结构,而且内部存储的是指针.所以一个slice修改了之后会影响到其他所有共用一个底层数组的slice.
append扩充:利用函数append()可以修改slice的结构,比如尾部追加元素
这里在容量(cap)可以容纳下新增元素的时候,slice的底层数组和cap是不会变化的,只是长度追加1.并且会修改底层数组对应下标的元素值:
而当cap本身不能容纳元素时则会新建底层数组并将元素复制到新数组中,在新数组的基础上建立slice.至于新建扩容的问题,因为版本不同会出现不同的结果,1.6上测试是扩容后的长度的2倍作为新的cap(windows7 32bit),1.7则是原cap的2倍作为新的cap(debian 3.16 64bit)
当然append的用法很多比如删除slice中的一部分元素
还有就是在建立slice的第三个参数的作用,指定cap的上限,可以保证底层数组的安全以及隐藏
slice部分,书里还提到了nil切片和空切片,nil切片指的是未初始化的,只声明的.空切片则是没有内容的
slice的迭代
可以通过传统的for循环迭代.
另外还有for range迭代切片
这里的格式化标识符可以
go doc fmt
在文档中看到,另外也有简单整理在这里
|
|
这里主要提两点:
- value的地址是同一个也就是每次迭代覆盖之前的值,这个在闭包一类的用法中需要注意
- 就是上面说的for range 中value提供的是元素值的副本
至于书里提到的多维切片,类比数组即可
映射(map)
创建以及初始化
- make关键字:
dict := make(map[string]int)
- 字面量初始化
dict := map[string]int{"first":1,"second":2}
仍然使用len()来获取map的长度,map的键需要是可以==操作的,且引用语义的不能作为key
nil映射和空映射
nil映射:var mapE map[int]string.这里==nil是true
空映射:上面的make以及这样操作的就是空映射dict := map[int]string{}
==nil自然是false
map的迭代以及使用
以key为索引操作,比如赋值:dict[1] = “one”
对nil映射赋值是会报错的
迭代使用for range:
书里还提到了判断map中某个元素是否存在:
这种方式是可以在nil映射上操作的.另一种方式不推荐,即只有value返回值,这就无法判断零值是确实存储在map中的还是不存在的.
删除map中的元素:delete(dict,key).
和slice一样,map也具有引用语义,所以在方法中传递map需要注意,一处修改,处处可见.delete仅用于map