书籍封面

Go语言精进之路:从新手到高手的编程思想、方法和技巧1

白明
  • 版权页
  • 作者简介
  • 推荐语
  • 推荐序
  • 前言
  • 第一部分 熟知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的输出信息