目录
第 1 章 Go 语言快速入门 1
1.1 Go 语言简介 1
1.1.1 Go 语言的历史 2
1.1.2 为什么选择 UNIX 而不是 Windows 3
1.1.3 Go 语言的优缺点 4
1.1.4 go doc 和 godoc 实用程序 5
1.2 Hello World! 6
1.2.1 函数简介 7
1.2.2 包简介 7
1.3 运行 Go 代码 8
1.3.1 编译 Go 代码 8
1.3.2 像脚本语言那样使用 Go 语言 8
1.3.3 导入格式和编码规则 9
1.4 Go 语言的重要特性 10
1.4.1 定义和使用变量 10
1.4.2 控制程序流 13
1.4.3 使用 for 循环和 range 进行迭代 15
1.4.4 获取用户输入 17
1.4.5 使用 error 变量区分输入类型 21
1.4.6 理解 Go 语言的并发模型 23
1.5 开发 Go 语言中的 which(1)工具 25
1.6 记录信息 27
1.6.1 log.Fatal()和 log.Panic() 29
1.6.2 写入自定义日志文件 30
1.6.3 在日志条目中打印行号 32
1.7 Go 语言中的泛型 33
1.8 开发一个基本的电话簿应用程序 35
1.9 本章练习 38
1.10 本章小结 39
1.11 附加资源 39
第 2 章 基本数据类型 40
2.1 error 数据类型 40
2.2 数值数据类型 43
2.3 非数值数据类型 46
2.3.1 字符串、字符和 rune 46
2.3.2 日期和时间 53
2.4 Go 常量 58
2.5 将相似数据分组 61
2.5.1 数组 61
2.5.2 切片 61
2.6 指针 79
2.7 生成随机数 82
2.7.1 生成随机字符串 83
2.7.2 生成安全的随机数 85
2.8 更新电话簿应用程序 85
2.9 本章练习 87
2.10 本章小结 87
2.11 附加资源 87
第 3 章 复合数据类型 88
3.1 映射 88
3.1.1 存储到一个 nil 映射 89
3.1.2 迭代映射 91
3.2 结构体 92
3.2.1 定义新的结构体 92
3.2.2 使用 new 关键字 93
3.2.3 结构体切片 95
3.3 正则表达式和模式匹配 97
3.3.1 Go 语言中的正则表达式 97
3.3.2 匹配姓名和姓氏 98
3.3.3 匹配整数 99
3.3.4 匹配记录中的字段 100
3.4 改进电话簿应用程序 101
3.4.1 处理 CSV 文件 101
3.4.2 添加索引 105
3.4.3 电话簿应用程序的改进版本 106
3.5 本章练习 114
3.6 本章小结 114
3.7 附加资源 114
第 4 章 反射和接口 115
4.1 反射 115
4.1.1 Go 结构体的内部结构 117
4.1.2 使用反射修改结构体值 119
4.1.3 反射的 3 个缺点 120
4.2 类型方法 121
4.2.1 创建类型方法 121
4.2.2 使用类型方法 122
4.3 接口 125
4.3.1 sort.Interface 接口 127
4.3.2 空接口 130
4.3.3 类型断言和类型开关 131
4.3.4 map[string]interface{}映射 135
4.3.5 error 数据类型 138
4.3.6 编写自己的接口 142
4.4 处理两种不同的 CSV 文件格式 147
4.5 Go 语言中的面向对象编程 151
4.6 更新电话簿应用程序 154
4.6.1 设置 CSV 文件值 155
4.6.2 使用 sort 包 156
4.7 本章练习 158
4.8 本章小结 158
4.9 附加资源 158
第 5 章 Go 包和函数 159
5.1 Go 包 159
5.2 函数 162
5.2.1 匿名函数 163
5.2.2 返回多个值的函数 163
5.2.3 可以命名的函数返回值 164
5.2.4 接收其他函数作为参数的函数 165
5.2.5 函数可以返回其他函数 167
5.2.6 可变参数函数 168
5.2.7 defer 关键字 172
5.3 开发自己的包 174
5.3.1 init()函数 175
5.3.2 执行顺序 175
5.4 使用 GitHub 存储 Go 包 176
5.5 用于操作数据库的包 178
5.5.1 了解数据库 179
5.5.2 存储 Go 包 183
5.5.3 Go 包的设计 184
5.5.4 Go 包的实现 186
5.5.5 测试 Go 包 193
5.6 模块 197
5.7 创建更好的包 197
5.8 生成文档 198
5.9 GitLab Runners 和 Go 205
5.9.1 初始版本的配置文件 205
5.9.2 最终版本的配置文件 207
5.10 GitHub Actions 和 Go 209
5.11 版本控制工具 211
5.12 本章练习 213
5.13 本章小结 213
5.14 附加资源 213
第 6 章 告诉 UNIX 系统该做什么 215
6.1 stdin、stdout 和 stderr 216
6.2 UNIX 进程 216
6.3 处理 UNIX 信号 217
6.4 文件 I/O 220
6.4.1 io.Reader 和 io.Writer 接口 220
6.4.2 使用和滥用 io.Reader 和 io.Writer 221
6.4.3 缓冲和非缓冲文件 I/O 225
6.5 读取文本文件 226
6.5.1 逐行读取文本文件 226
6.5.2 逐字读取文本文件 227
6.5.3 逐字符读取文本文件 229
6.5.4 从/dev/random 读取 230
6.5.5 从文件中读取特定数量的数据 231
6.6 写入文件 232
6.7 处理 JSON 数据 235
6.7.1 使用 Marshal()和 Unmarshal() 235
6.7.2 Go 结构体和 JSON 237
6.7.3 以流的形式读取和写入 JSON 数据 238
6.7.4 美观打印 JSON 记录 239
6.8 处理 XML 数据 241
6.9 处理 YAML 数据 243
6.10 viper 包 245
6.10.1 使用命令行标志 246
6.10.2 读取 JSON 配置文件 248
6.11 cobra 包 252
6.11.1 基于 3 条命令的实用工具 253
6.11.2 添加命令行标志 254
6.11.3 创建命令行别名 255
6.11.4 创建子命令 255
6.12 在 UNIX 文件系统中查找循环 256
6.13 Go 1.16 中的新特性 259
6.13.1 嵌入文件 259
6.13.2 ReadDir 和 DirEntry 262
6.13.3 io/fs 包 264
6.14 更新电话簿应用程序 266
6.14.1 使用 cobra 266
6.14.2 存储和加载 JSON 数据 267
6.14.3 实现 delete 命令 268
6.14.4 实现 insert 命令 269
6.14.5 实现 list 命令 269
6.14.6 实现 search 命令 269
6.15 本章练习 271
6.16 本章小结 271
6.17 附加资源 272
第 7 章 Go 语言中的并发性 273
7.1 进程、线程和协程 274
7.2 Go 调度器 274
7.2.1 GOMAXPROCS 环境变量 276
7.2.2 并发和并行 277
7.3 协程 278
7.3.1 创建一个协程 278
7.3.2 创建多个协程 279
7.3.3 等待协程完成 279
7.3.4 Add()和 Done()调用的次数不同 281
7.3.5 使用协程创建多个文件 283
7.4 通道 283
7.4.1 向通道写入和从通道读取 284
7.4.2 从已关闭的通道接收 287
7.4.3 作为函数参数的通道 288
7.5 竞态条件 288
7.6 select 关键字 291
7.7 协程超时 293
7.7.1 main()中的协程超时 293
7.7.2 main()之外的协程超时 294
7.8 重新审视 Go 通道 295
7.8.1 缓冲通道 296
7.8.2 nil 通道 298
7.8.3 工作池 299
7.8.4 信号通道 303
7.9 共享内存和共享变量 305
7.9.1 sync.Mutex 类型 306
7.9.2 sync.RWMutex 类型 308
7.9.3 atomic 包 311
7.9.4 使用协程共享内存 312
7.10 闭包变量和 go 语句 315
7.11 context 包 317
7.12 semaphore 包 322
7.13 本章练习 325
7.14 本章小结 325
7.15 附加资源 325
第 8 章 构建 Web 服务 326
8.1 net/http 包 326
8.1.1 http.Response 类型 326
8.1.2 http.Request 类型 327
8.1.3 http.Transport 类型 328
8.2 创建一个 Web 服务器 329
8.3 更新电话簿应用程序 332
8.3.1 定义 API 332
8.3.2 实现处理程序 333
8.4 将指标公开与 Prometheus 341
8.4.1 runtime/metrics 包 341
8.4.2 公开指标 343
8.4.3 读取指标 351
8.4.4 将指标放入 Prometheus 352
8.4.5 在 Grafana 中可视化 Prometheus 指标 356
8.5 开发 Web 客户端 357
8.5.1 使用 http.NewRequest()改进客户端 359
8.5.2 为电话薄服务创建客户端 362
8.6 创建文件服务器 368
8.7 对 HTTP 连接进行超时设置 371
8.7.1 使用 SetDeadline() 371
8.7.2 在客户端设置超时周期 372
8.7.3 在服务器端设置超时周期 375
8.8 本章练习 376
8.9 本章小结 377
8.10 附加资源 377
第 9 章 TCP/IP 和 WebSocket 378
9.1 TCP/IP 378
9.2 net 包 380
9.3 开发 TCP 客户端 380
9.3.1 利用 net.Dial()开发 TCP 客户端 380
9.3.2 利用 net.DialTCP()开发 TCP 客户端 382
9.4 开发 TCP 服务器 384
9.4.1 利用 net.Listen()开发 TCP 服务器 384
9.4.2 利用 net.ListenTCP()开发 TCP 服务器 386
9.5 开发 UDP 客户端 389
9.6 开发 UDP 服务器 391
9.7 开发并发 TCP 服务器 394
9.8 使用 UNIX 域套接字 396
9.8.1 UNIX 域套接字服务器 396
9.8.2 UNIX 域套接字客户端 399
9.9 创建 WebSocket 服务器 401
9.9.1 服务器的实现 402
9.9.2 使用 websocat 405
9.9.3 使用 JavaScript 406
9.10 开发 WebSocket 客户端 409
9.11 本章练习 413
9.12 本章小结 414
9.13 附加资源 414
第 10 章 REST APIs 415
10.1 REST 简介 415
10.2 开发 RESTful 服务器和客户端 417
10.2.1 RESTful 服务器 418
10.2.2 RESTful 客户端 426
10.3 创建一个功能性的 RESTful 服务器 435
10.3.1 REST API 435
10.3.2 使用 gorilla/mux 436
10.3.3 使用子路由器 437
10.3.4 与数据库协作 437
10.3.5 测试 restdb 包 442
10.3.6 实现 RESTful 服务器 444
10.3.7 测试 RESTful 服务器 448
10.4 开发 RESTful 客户端 451
10.4.1 创建命令行客户端的结构 452
10.4.2 实现 RESTful 客户端命令 453
10.4.3 创建 RESTful 客户端 457
10.4.4 处理多个 REST API 版本 459
10.5 上传和下载二进制文件 459
10.6 使用 Swagger 进行 REST API 文档编写 464
10.6.1 为 REST API 编写文档 466
10.6.2 生成文档文件 469
10.6.3 提供文档文件服务 470
10.7 本章练习 472
10.8 本章小结 473
10.9 附加资源 473
第 11 章 代码测试与性能分析 474
11.1 代码优化 474
11.2 基准测试代码 475
11.2.1 重写 main()函数 476
11.2.2 基准测试缓冲写入和读取 477
11.2.3 benchstat 实用工具 481
11.2.4 错误定义的基准测试函数 481
11.3 代码性能分析 482
11.3.1 命令行应用程序的性能分析 483
11.3.2 HTTP 服务器性能分析 486
11.3.3 Go 性能分析器的 Web 界面 488
11.4 go tool trace 实用程序 488
11.4.1 从客户端追踪 Web 服务器 491
11.4.2 访问 Web 服务器的所有路由 494
11.5 测试 Go 代码 499
11.5.1 编写./ch03/intRE.go 测试 499
11.5.2 TempDir()函数 500
11.5.3 Cleanup()函数 501
11.5.4 testing/quick 包 503
11.5.5 超时测试 505
11.5.6 测试代码覆盖率 506
11.5.7 发现 Go 语言中的不可达代码 509
11.6 测试基于数据库后端的 HTTP 服务器 510
11.7 模糊测试 516
11.8 交叉编译 517
11.9 使用 go:generate 518
11.10 生成示例函数 521
11.11 本章练习 522
11.12 本章小结 523
11.13 附加资源 523
第 12 章 与 gRPC 协同工作 524
12.1 gRPC 简介 524
12.2 定义接口定义语言文件 525
12.3 创建 gRPC 服务器 528
12.4 开发 gRPC 客户端 532
12.5 本章练习 536
12.6 本章小结 536
12.7 附加资源 537
第 13 章 Go 语言中的泛型 538
13.1 泛型简介 538
13.2 约束条件 540
13.3 使用泛型定义新数据类型 543
13.4 接口和泛型 546
13.5 反射和泛型 549
13.6 本章练习 551
13.7 本章小结 551
13.8 附加资源 552
附录 553
