Parts of A Tour Of Go
指针
Go
具有指针,指针保存了变量的内存地址。
类型*T
是指向T
类型值的指针,其零值为nil
。&
操作符会生成一个指向其操作数的指针。*
操作符表示指针指向的底层值。
1 | // 类型声明 |
与C
不同,Go
没有指针运算。
1 | package main |
结构体
一个结构体struct
就是一个字段的集合。type
声明用于定义类型。
1 | package main |
结构体字段用点号来访问。
1 | package main |
结构体字段也可以用结构体指针来访问。
1 | package main |
可以通过直接列出字段的值来分配一个结构体。
使用Name:
语法可以仅列出部分字段(顺序无关)。
特殊前缀&
返回一个指向结构体的指针。
1 | package main |
数组
类型[n]T
表示拥有n
个T
类型的值的数组。
数组的长度是其类型的一部分,因此数组不能改变大小。
1 | package main |
切片
每个数组的大小都是固定的,而切片可以实现动态大小。
在实践中,切片比数组更常用。
类型[]T
表示一个元素类型为T
的切片。
1 | a[0:5] // 为数组a的前五个元素创建一个切片 |
1 | package main |
切片就像数组的引用
切片并不存储任何数据,它只是描述了底层数组中的一段。
更改切片的元素会修改其底层数组中对应的元素。
与它共享底层数组的切片都会观测到这些修改。
1 | package main |
切片语法
切片语法类似于没有长度的数组语法。
1 | // 数组语法 |
1 | package main |
切片的默认行为
在进行切片时,你可以利用它的默认行为来忽略上下界。
切片下界默认值为0
,上界的默认值为该切片的长度。
1 | var a [10]int |
1 | package main |
切片的长度和容量
切片拥有长度
和容量
两个属性。
切片的长度就是它所包含的元素个数。
切片的容量是从它第一个元素开始数,到其底层数组元素末尾的个数。
切片s
的长度和容量可以通过表达式len(s)
和cap(s)
来获取。
可以通过重新切片来扩展一个切片,给它提供足够的容量。
1 | package main |
len
只能在cap
范围内改变。
nil
切片
切片的零值是nil
。nil
切片的长度和容量为0
且没有底层数组。
1 | package main |
用make
创建切片
切片可以使用内建函数make
来创建。make
函数会创建一个元素全为零值的数组,并返回一个引用了该数组的切片。
1 | package main |
切片的切片
切片可包含任何类型,包括其它切片。
1 | package main |
向切片追加元素append
Go
提供了内建函数append
为切片追加新的元素。
1 | func append(s []T, vs ...T) []T |
append
的第一个参数s
是一个元素类型为T
的切片,其余类型为T
的值将会追加到该切片的末尾。
当s
的底层数组太小,不足以容纳所有给定的值时,append
会分配一个更大的数组,返回的切片会指向这个新分配的数组。
Go切片:用法和本质
1 | package main |
range
for
循环的range
形式可遍历切片或映射。
当使用for
循环遍历切片时,每次迭代都会返回两个值。第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本。
1 | package main |
可以将下标或值赋予_
来忽略它。
若只需要索引,去掉, value
的部分即可。
1 | package main |
练习: 切片
1 | package main |
映射
映射将键(key)映射到值(value)。
映射的零值为nil
。nil
映射没有键,也不能添加键。make
函数会返回给定类型的映射,并将其初始化备用。
1 | package main |
映射语法
映射的语法与结构体相似,不过必须有键名。
1 | package main |
若顶级类型只是一个类型名,可以在语法中省略它。
1 | package main |
修改映射
1 | package main |
练习: 映射
实现WordCount
。它应当返回一个映射,其中包含字符串中每个单词的个数。
函数wc.Test
会对此函数执行一系列测试用例,并输出成功还是失败。
1 | package main |
函数值
函数可以像其它值一样传递。
函数值可以用作函数的参数或返回值。
1 | package main |
函数的闭包
Go
函数可以是一个闭包。闭包是一个函数值,它引用了其函数体之外的变量。
该函数可以访问并赋予其引用的变量的值,换句话说,这些变量被“绑定”在该函数中了。
1 | package main |
练习: 斐波纳契闭包
实现一个fibonacci
函数,它返回一个函数(闭包),该闭包返回一个斐波纳契数列 (0, 1, 1, 2, 3, 5, ...)
1 | package main |