图书目录

目录

第 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