go 语言实战
1. 介绍
2. Go 包执行顺序
- 获取数据 -> 一组等待搜索的数据源
- 执行搜索 -> 使用接口进行匹配-发送结果-报告任务完成
- 跟踪结果 -> 停止结果
- 显示结果
main search feed match RSS 匹配器
3. 打包和工具链
-
导入包查找顺序
/usr/local/go/src/pkg/home/myproject/src/home/mylibraries/s -
更改包导入名
myfmt "mylib/fmt"导入的包一定要被使用,否则需要用 “_” -
函数 init 会在开始时被调用
-
go 命令
go run 运行 go 程序
go build 构建包打包成 exe,"…“代表所有字符串
go get 导入网络包的时候会出错,需要使用 get 来获取,如果仍失败,需要下载到本地,并且将路径名改成和包名一致,本地导入
go get -u golang.org/x/tools/cmd/godoc
import "./model"
go clean 删除编译生成的可执行文件
go doc
可查看本地文档,变成网页模式查看
go doc tar
godoc -http=:6060
安装
创建目录下载包
如果创建在 program 目录下没有权限执行,因此创建在 gopath 下的 src
|
|
go env 修改配置环境
|
|
go vet 检查常见错误
介绍 godep/gb/vender
4. 数组/切片/映射
如果定义全局变量需要用 var 来声明,不能用:=
-
数组 数组赋值的时候应该注意长度一致,否则报错 如果数组长度不确定,可以使用 … 代替数组的长度
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}或balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0} -
切片 参数包含容量和长度
slice := make([]string, 3, 5)
创建 nil 切片
var slice []int
声明空切片
slice := make{[int, 0]}
或
slice := [] int {}
切片在赋值的时候只写长度,重新 append 时会开辟新空间,如果赋值时加上容量,append 会在原位置上修改值,影响原始数据
- 映射
创建和初始化映射
dict := make(map[string]int)
dict := map[string]string{"A":"a"}
使用映射字面量声明空映射
dict := map[[] string] int{} 报错
创建一个映射,使用字符串切片做为值
dict := map[int][]string{}
关于 map
-
变量名以小写开头不公开,其他包可以间接调用,一个函数可以返回一个未公开类型的值
-
map 需要先用 make 构造,否则会报错,因为 map 变量默认零值 nil
5. 类型
类
|
|
方法
|
|
传值,传指针,传地址
切片/映射/通道/接口/函数
方法传值与传指地址区别 直接传是传递副本,*表示传引用,&表示传地址 方法是将参数的副本做操作,如果要改变参数值,需要将参数地址传到函数
数组是值传递,切片是引用传递
- 传值
go 语言中基本数据类型、结构体、数组都是传值
将变量的副本传递给形参 传递给函数的参数是被传数据的的副本,因此对形参(也就副本)的值进行更改操作时,并不会影响原始数据 同时,由于传值时,需要拷贝一份数据给形参,因此比较耗费资源。
-
传引用 将变量的地址复制一份传递给形参,它也可以看作传值,只不过传的是地址值的副本
-
传地址
知识点
- 多态指定义了一个接口类型后,可以定义其他方法来实现改写改类型
- 接口是声明了一组行为并支持多态的类型
- struct 或者通过指定已存在的类型声明用户定义的类型
- 类型本质 给类型增加删除某个值,是创建新值还是改变当前值,创建新值该类型方法就是值接收者,修改当前值就是指针接收者,同时影响内部传递类型值的方式
内置类型 go 语言中类型的默认值。如下:
数值类型(如 int8、int16、uint 等),默认值为 0 布尔类型,默认值为 false 字符串类型,默认值为”" 指针、通道、切片、字典等,默认值为 nil 复合类型的默认值,为所包含类型的默认值
引用类型 切片/映射/通道/接口/函数,创建的变量为标头值
- 嵌入关系 值 方法接收方 T 类型包含 (t T) *T 类型包含 (t T) 和 (t *T)
方法接收方 值 (t T) T 和*T (t *T) *T
类型 S 包含匿名字段 T,则 S 和S 方法集包含 T 方法 类型 S 包含匿名字段T,则 S 和*S 方法集包含 T + T 方法 不管嵌入的是 T 还是T,*S 方法集包含 T + *T 方法
当 user 定义一个用户类型,方法实现一个通过 user 类型值的指针,admin 包含 user 类型,admin 可以调用 user 内部的方法,提升到外部类型,当 admin 也实现了该方法,则不会调用 user 方法,可以通过直接访问 user 方法
- 未公开标识符 定义类型,小写开头为未公开标识符 文件夹应该同包名相同 当需要调用未公开标识符时,可以创建一个工厂函数 New 来返回该未公开标识符
6. 并发
7. 并发模式
8. 标准库
log 包
json 编码解码
Writer 和 Reader
9. 测试和性能
单元测试
使用 go test -v(提供冗余输出),没有加上除非失败,否则看不到测试输出 go 语言约定,_test.go 结尾的文件是测试文件,测试函数需要用 Test 开头,函数的签名必须接收一个指向 testing.T 类型的指针并且不返回任何值,
表组测试
建立多个值传入测试,查看不同
模仿调用
写一个 mockServer 模拟服务器返回
基准测试
使用 strconv 和 testing 包,文件名需要以_test.go 结尾
|
|
go test -v -run=“none” -bench=“BenchmarkSprintf”
-run 传递 none 保证运行基准测试前没有单元测试被运行 b.ResetTimer()初始化计时器 -benchmem 提供每次操作分配内存的次数,以及总共分配内存的字节数,allocs/op