字符串 string
字符串 string
是 Go 中的基本类型, 它是一个不可变的 UTF-8 字符(byte)序列.
特点和注意事项如下:
- 字符串默认值不是
nil
, 而是""
- 允许以索引方式访问字节数组, 但不能获取元素地址或对其中元素修改
- 可以使用反引号(`)定义不做任何转义处理的原始字符串, 支持跨行
1 | import ( |
- 使用 for 循环遍历字符串时, 分
byte
和rune
两种方式
1 | import ( |
- 要修改字符串, 需要将其转换为
[]rune
或[]byte
数组, 待修改完成后再使用string()
强制转换回来.
数组 array
数组的一般形式如下:
1 | var name [len]Type = [len]Type{element1, element2, element3...} |
特点和注意事项如下:
- 数组用于保存相同类型元素的集合, 数组是有长度的. 只有元素类型与长度都相同的数组才属于同一种类型.
- 数组支持使用索引访问元素内容
- 对于定义时不确定长度的数组, 可用
[...]Type
进行定义, 但一旦初始化赋值, 其长度也会随之确定. 定义多维数组时, 仅允许第一维数组长度使用...
- 内置函数
len()
,cap()
均返回数组的第一维长度 - 指针数组是指元素为指针的数组, 如
arr := [3]*int{&x, &y}
, 数组指针是内存中数组的地址, 如&arr
. 数组指针可来操作元素 - 数组是值类型, 赋值和传参都会复制整个数组数据, 可以使用指针或切片,避免数据复制
代码示例如下:
1 | import ( |
切片 slice
切片的一般形式如下
1 | var sliceName []Type = []Type{element1, element2, element3...} |
特点和注意事项如下:
- 可使用内置函数
make([]Type, len, cap)
初始化一个长度为len
元素值为默认值的切片, 并完成长度为cap
用于存储底层数据的数组的内存分配. 其中cap
为容量, 可以省略(默认为len
), 否则必须大于等于len
. 切片的长度及容量均可超过其初始定义时的长度和容量, 此时会为底层数组重新分配内存地址空间 - 切片是引用类型, 所有在函数内的对其元素的操作都会作用到其底层数据结构上
- 可基于数组或数组指针创建切片, 以开始索引或结束索引确定切片所引用的数据字段. 不支持反向索引
- 使用形如
var s []int
创建的切片为nil
- 切片支持使用索引号访问元素内容
append()
可用于向切片尾部添加数据, 返回对象的内存地址不会发生改变, 但是如果append
后的切片超过cap
容量, 则会为底层数组重新分配内存空间. 新分配的cap
容量为一般初始cap
容量的整数倍copy(dst, src []Type)
可用于在两个切片对象间复制数据, 最终所复制的数据以较短的切片长度为准.
代码示例如下:
1 | import ( |
1 | import "fmt" |
字典 map
字典的一般形式如下:
1 | var mapName map[KeyType]ValueType = map[KeyType]ValueType{ |
特点和注意事项如下:
- 字典是引用类型, 一般使用
make(map[KeyType]ValueType, size)
或初始化语句表达式创建. 内容为空的字典已经做了初始化操作, 与nil
是不同的 - 函数
len()
返回当前键值对数量 - Key 必须支持等值比较(
==
,!=
), 类型可以为数字,字符串,指针,数组,结构体,接口等类型.常见的一般为字符串 - 访问键值时, 推荐使用
v, ok := m[key]
模式. 可以通过ok
判断键是否存在. 如果存在,ok
会返回true
; 否则, 返回false
- 字典是一种无序键值对集合, 对字典进行 for-range 遍历, 每次遍历的次序都不相同
- 因为访问安全和哈希算法的缘故, 字典被设计为 “not addressable”, 因此不能直接修改
value
成员(结构体或数组). 只能返回整个value
, 修改后重新对字典赋值. 或直接使用指针类型
示例代码如下:
1 | import ( |
结构体 struct
struct
将多个不通类型的字段序列打包成一个复合类型, 类似于类
的概念. 一般定义方式如下
1 | type structName struct{ |
特点和注意事项如下:
- 字段名必须唯一, 支持使用
_
补位字段名(忽略该字段). 支持直接指定字段类型, 从而使用匿名字段, 实际上是使用与类型名相同的字段 - 可直接使用
structName.fieldName
访问结构体字段. 对于匿名字段, 可以使用structName.fieldType
访问该匿名字段 - 由于 Go 语言底层的优化, 可使用结构体指针直接操作结构体字段 如, 如果
p := &structName
, 则*(p).fieldName
等价于p.fieldName
- 结构体支持多个结构体嵌套, 可以理解为:内层结构体作为外层结构体一个或多个匿名或非匿名字段.
- 结构体嵌套过程中, 如果内层结构体(innerStructName)与外层结构体(outerStructName)有相同的字段
fieldName
, 则outerStructName.fieldName
表示访问外层结构体. 内层结构体fieldName
字段只能通过outerStructName.innerStructFieldName.fieldName
访问.
如果外层结构体没有内层结构体字段innerFieldName
, 则可以通过outerStructName.innerFieldName
访问innerFieldName
字段.其实就是就近原则 - 如果多个内层结构体有相同的字段, 则必须指定内层结构体名称才能访问到该字段,否则会编译报错
示例代码如下:
1 | import ( |
字段标签
字段标签并不是注释, 而是用来对字段进行描述的元数据.
- 在运行期间, 可用反射获取标签信息, 常被用作格式校验, 数据库关系映射等.
- 由于 Go 中私有变量与可导入变量是通过首字母大小写区分的. 因此对于可导入变量, 还可以用作 json 格式化输出字段
示例如下:
1 | import ( |