封面
版权页
作者简介
推荐语
推荐序
前言
第一部分 熟知Go语言的一切
第1条 了解Go语言的诞生与演进
1.1 Go语言的诞生
1.2 Go语言的早期团队和演进历程
1.3 Go语言正式发布并开源
第2条 选择适当的Go语言版本
2.1 Go语言的先祖
2.2 Go语言的版本发布历史
2.3 Go语言的版本选择建议
第3条 理解Go语言的设计哲学
3.1 追求简单,少即是多
3.2 偏好组合,正交解耦
3.3 原生并发,轻量高效
3.4 面向工程,“自带电池”
第4条 使用Go语言原生编程思维来写Go代码
4.1 语言与思维——来自大师的观点
4.2 现实中的“投影”
4.3 Go语言原生编程思维
第二部分 项目结构、代码风格与标识符命名
第5条 使用得到公认且广泛使用的项目结构
5.1 Go项目的项目结构
5.2 Go语言典型项目结构
第6条 提交前使用gofmt格式化源码
6.1 gofmt:Go语言在解决规模化问题上的最佳实践
6.2 使用gofmt
6.3 使用goimports
6.4 将gofmt/goimports与IDE或编辑器工具集成
第7条 使用Go命名惯例对标识符进行命名
7.1 简单且一致
7.2 利用上下文环境,让最短的名字携带足够多的信息
第三部分 声明、类型、语句与控制结构
第8条 使用一致的变量声明形式
8.1 包级变量的声明形式
8.2 局部变量的声明形式
第9条 使用无类型常量简化代码
9.1 Go常量溯源
9.2 有类型常量带来的烦恼
9.3 无类型常量消除烦恼,简化代码
第10条 使用iota实现枚举常量
第11条 尽量定义零值可用的类型
11.1 Go类型的零值
11.2 零值可用
第12条 使用复合字面值作为初值构造器
12.1 结构体复合字面值
12.2 数组/切片复合字面值
12.3 map复合字面值
第13条 了解切片实现原理并高效使用
13.1 切片究竟是什么
13.2 切片的高级特性:动态扩容
13.3 尽量使用cap参数创建切片
第14条 了解map实现原理并高效使用
14.1 什么是map
14.2 map的基本操作
14.3 map的内部实现
14.4 尽量使用cap参数创建map
第15条 了解string实现原理并高效使用
15.1 Go语言的字符串类型
15.2 字符串的内部表示
15.3 字符串的高效构造
15.4 字符串相关的高效转换
第16条 理解Go语言的包导入
16.1 Go程序构建过程
16.2 究竟是路径名还是包名
16.3 包名冲突问题
第17条 理解Go语言表达式的求值顺序
17.1 包级别变量声明语句中的表达式求值顺序
17.2 普通求值顺序
17.3 赋值语句的求值
17.4 switch/select语句中的表达式求值
第18条 理解Go语言代码块与作用域
18.1 Go代码块与作用域简介
18.2 if条件控制语句的代码块
18.3 其他控制语句的代码块规则简介
第19条 了解Go语言控制语句惯用法及使用注意事项
19.1 使用if控制语句时应遵循“快乐路径”原则
19.2 for range的避“坑”指南
19.3 break跳到哪里去了
19.4 尽量用case表达式列表替代fallthrough
第四部分 函数与方法
第20条 在init函数中检查包级变量的初始状态
20.1 认识init函数
20.2 程序初始化顺序
20.3 使用init函数检查包级变量的初始状态
第21条 让自己习惯于函数是“一等公民”
21.1 什么是“一等公民”
21.2 函数作为“一等公民”的特殊运用
第22条 使用defer让函数更简洁、更健壮
22.1 defer的运作机制
22.2 defer的常见用法
22.3 关于defer的几个关键问题
第23条 理解方法的本质以选择正确的receiver类型
23.1 方法的本质
23.2 选择正确的receiver类型
23.3 基于对Go方法本质的理解巧解难题
第24条 方法集合决定接口实现
24.1 方法集合
24.2 类型嵌入与方法集合
24.3 defined类型的方法集合
24.4 类型别名的方法集合
第25条 了解变长参数函数的妙用
25.1 什么是变长参数函数
25.2 模拟函数重载
25.3 模拟实现函数的可选参数与默认参数
25.4 实现功能选项模式
第五部分 接口
第26条 了解接口类型变量的内部表示
26.1 nil error值!= nil
26.2 接口类型变量的内部表示
26.3 输出接口类型变量内部表示的详细信息
26.4 接口类型的装箱原理
第27条 尽量定义小接口
27.1 Go推荐定义小接口
27.2 小接口的优势
27.3 定义小接口可以遵循的一些点
第28条 尽量避免使用空接口作为函数参数类型
第29条 使用接口作为程序水平组合的连接点
29.1 一切皆组合
29.2 垂直组合回顾
29.3 以接口为连接点的水平组合
第30条 使用接口提高代码的可测试性
30.1 实现一个附加免责声明的电子邮件发送函数
30.2 使用接口来降低耦合
第六部分 并发编程
第31条 优先考虑并发设计
31.1 并发与并行
31.2 Go并发设计实例
第32条 了解goroutine的调度原理
32.1 goroutine调度器
32.2 goroutine调度模型与演进过程
32.3 对goroutine调度器原理的进一步理解
32.4 调度器状态的查看方法
32.5 goroutine调度实例简要分析
第33条 掌握Go并发模型和常见并发模式
33.1 Go并发模型
33.2 Go常见的并发模式
第34条 了解channel的妙用
34.1 无缓冲channel
34.2 带缓冲channel
34.3 nil channel的妙用
34.4 与select结合使用的一些惯用法
第35条 了解sync包的正确用法
35.1 sync包还是channel
35.2 使用sync包的注意事项
35.3 互斥锁还是读写锁
35.4 条件变量
35.5 使用sync.Once实现单例模式
35.6 使用sync.Pool减轻垃圾回收压力
第36条 使用atomic包实现伸缩性更好的并发读取
36.1 atomic包与原子操作
36.2 对共享整型变量的无锁读写
36.3 对共享自定义类型变量的无锁读写
第七部分 错误处理
第37条 了解错误处理的4种策略
37.1 构造错误值
37.2 透明错误处理策略
37.3 “哨兵”错误处理策略
37.4 错误值类型检视策略
37.5 错误行为特征检视策略
第38条 尽量优化反复出现的if err != nil
38.1 两种观点
38.2 尽量优化
38.3 优化思路
第39条 不要使用panic进行正常的错误处理
39.1 Go的panic不是Java的checked exception
39.2 panic的典型应用
39.3 理解panic的输出信息
更新时间:2022-01-04 17:35:54