Statistics
35
Views
0
Downloads
0
Donations
Uploader

高宏飞

Shared on 2025-12-14
Support
Share

Go圈知名架构师和布道者撰写,3大Go社区力荐,哲学、思维、技巧等66个主题快速帮你写出高质量代码) (华章程序员书库)

Tags
No tags
Publisher: 北京华章图文信息有限公司
Language: 英文
File Format: PDF
File Size: 8.5 MB
Support Statistics
¥.00 · 0times
Text Preview (First 20 pages)
Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

(This page has no text content)
Table of Contents 版权页 目录 作者简介 推荐语 推荐序 前言 第一部分 熟知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的输出信息
华章程序员书库 Go语言精进之路:从新手到高手的编程思想、方法 和技巧1 Go Programming from Beginners to Masters: Thinking, Methods and Techniques 白明 著 ISBN:978-7-111-69821-0 本书纸版由机械工业出版社于2022年出版,电子版由华章分社(北京华 章图文信息有限公司)出品,授权北京世纪卓越信息技术有限公司在全 球范围内制作与发行。 版权所有,侵权必究 客服热线:+ 86-10-68995265 客服信箱:service@bbbvip.com 官方网址:www.hzmedia.com.cn 新浪微博 @华章数媒 微信公众号 华章电子书(微信号:hzebook)
目录 作者简介 推荐语 推荐序 前言 第一部分 熟知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的输出信息
作者简介 白明(Tony Bai) 资深Go技术专家和架构师,有超过10年的服务端架构设计和开发 经验,擅长服务器后端编程。曾任东软集团开发部技术总监和东网科技 高级架构师,现为东软睿驰智能网联汽车业务线车联网平台的高级架构 师。精通Go、C、Python、Shell、Linux、Rancher、Docker、 OpenStack、Kubernetes等技术栈。 《七周七语言》译者之一,GopherChina大会、开源中国源创会讲 师,麦思博客座培训师,tonybai.com技术博客博主。
推荐语 2017年我曾邀请白明到GopherChina分享过如何用Go风格来写Go代 码,当时就很期待更多Go风格方面的技术干货。这次白老师给我们带来 了这本书,它系统讲解了如何运用Go思维、Go风格、Go最佳实践来写 好代码,鞭辟入里。 ——谢孟军 积梦智能CEO/GoCN社区和GopherChina发起人 这本书内容全面、翔实,涵盖Go基本语法、Go运行时底层实现、 常用标准库和第三方库的使用、代码设计模式,以及官方工具链和常见 第三方工具的使用。因此,本书既可以用来巩固Go知识,也可以用来开 拓技术视野。 ——老貘 《Go语言101》作者 Go语言是一门入门相对简单的编程语言,我的很多使用其他编程语 言的朋友,一天时间就可以学完Go语言的基础知识,但是当他们想进一 步学习Go语言时,却又感到茫然,无从下手。目前市面上有一些Go入 门的书,也有一些专门讲Go高级专题的书,但是鲜有帮助Go入门者提 高的书,白明老师的这本书正好填补了这一空白。本书从思维和实践两 个层面讲解如何写出地道的Go风格的代码,值得想进一步提高Go编程 水平的朋友拥有。 ——晁岳攀(鸟窝) 微服务框架rpcx的作者/资深工程师 白明是国内Go语言圈子里的资深开发者,这本书脱胎于他丰富的编 程经验,其中一条条的总结饱含着他对Go语言的热爱。对于广大的Go 语言爱好者来说,通过这本书充分吸取一位高手的经验实在是一个难得 的机会。相信本书能够帮助那些热爱Go语言编程的朋友们更上一层楼。 ——郝林 《Go语言核心36讲》和《Go并发编程实战》作者 本书有两大特色:第一,通过条目的方式覆盖Go语言的方方面面; 第二,旨在道出如何写出符合Go思维和语言惯例的高质量代码。独特的 组织方式让你在掌握Go语法的同时,更能写出Go风格的代码。白明老 师是早期的Go语言布道者,写的博文通俗易懂,近些年还一直更新 Gopher Daily,让大家第一时间掌握Go的动态。这本不一样的Go书,值 得你拥有。 ——徐新华(polarisxu) Go语言中文网站长/《Go语言编程之 旅》作者
推荐序 既然你翻开了这本关于Go语言的书,那就说明你对Go语言有兴 趣,打算学习一下Go语言。不过,在你继续翻阅之前,我先问你一个问 题:“你觉得Go语言简单吗?” 简单?不简单? 对于这个问题,有的人会说Go语言很简单,一个晚上就能学完所有 语法,也有人会说Go语言不简单,要做到运用自如需要大量磨炼。 为什么会有两个截然不同的答案?因为他们回答的其实并不是同一 个问题。真正的问题是: Go语言入门简单吗?简单! Go语言精通简单吗?不简单! 从入门到精通的路有多远呢?大概相当于从学会说话到写文章发表 的距离吧!能说话的人有的是,一般一岁的小朋友就可以做到。但能写 文章发表的人有多少呢?即便是在自媒体如此发达的今天,能够利用文 字表达自己的也只有少数人,大多数人只能作为信息的接收者。 同样,入门的程序员数量庞大,但真正精通的程序员却为数不多。 一个有追求的程序员绝不满足于会写Hello World,他会望向那座叫 作“精通”的高峰,但怎样攀上高峰是摆在很多人面前的现实问题。 要精通一门语言,最好的方式是跟着一个已经精通这门语言的人系 统学习。然而,并不是每个人都有这样的机会。不是每个人身边都有一 位精通这门语言的高手,即便有,高手也不见得有意愿、有能力把自己 的知识体系整理出来,倾囊相授。好在这个世界上还有很多高手乐于分 享,把知识系统地整理了出来,我们才有机会向他们学习。 从入门到进阶 入门的书与进阶的书有哪些不同呢?入门的书一般讲的是语言本 身,按照一个合适的顺序介绍语法规范中的各种细节,最多再增加一些 标准库的使用方式就够了。各种语言的差异无非是语法和标准库数量的 多寡,基本结构大体类似。
对于编程新手而言,难的并不是掌握这些语法和标准库,而是建立 一种思维方式。你只要学会了任何一门程序设计语言,通过了建立思维 方式的关卡,再去学习一门新的程序设计语言,就只需要学习具体的语 法和一些这门语言特有的知识。所以,程序员通常是“一专多能”的,除 了自己最拿手的那门语言,还会使用很多门其他的语言,而更厉害的家 伙甚至是“多专多能”的。 那一本进阶的书能告诉我们什么呢?它会告诉我们一个生态。如果 说入门书是在练习场上模拟,那么进阶的书就是在真实战场上拼杀。在 真实世界中编写代码解决的不再是一个个简单的问题,而是随着需求不 断膨胀的复杂问题。我们编写的不是“写过即弃”的代码,所以必须面对 真实的问题,比如如何做设计,如何组织代码,如何管理第三方的程序 库,等等。这些在很多人眼中琐碎的问题其实是我们每日都要面对的问 题,很多技术团队正是因为没有遵循这些方面的最佳实践而陷入了无尽 的深渊。而这些内容显然超出了语言本身的范畴,属于生态的范围。 进阶的书很重要,然而,写好进阶的书却不是一件容易的事。一个 初出茅庐的程序员就可以写入门书,而只有经验丰富的程序员才能写出 进阶的书。这种经验不仅在于写了很多年代码,还在于能够向行业动态 看齐。只有这样,写出来的才不是个人偏见,而是行业共识。 如果你是一名Go程序员,而且不满足于在入门水平徘徊,那么这就 是为你准备的一本进阶书。 一个高手,一本进阶书 本书的作者白明是一位有超过十年系统编程经验的资深程序员。这 里说的程序员指的是那些真正热爱编程,把编程当作一门手艺不断打磨 的人。虽然他有着诸如架构师之类的头衔,但骨子里他依然是个不断精 进的程序员。 他刚刚开始工作时我们就相识了,那时他就是一个热爱编程的人, 时隔多年依然如故。他刚开始用C语言写通信网关这种有着各种严苛要 求的软件,但一直在寻找更好的工具。Go的出现让他眼前一亮:一方 面,Go与C一脉相承,有着共同的创造者;另一方面,Go引入了一些更 加现代的特性,让它更适合大规模开发。于是,白明把自己更多的时间 献给了Go。一晃十多年过去,Go由他最初的个人爱好变成了他日常工 作中使用的语言。 除了在工作中使用Go,白明还是一位非常积极的分享者,经常在 Go社区分享内容。他不仅主导了一个叫Gopher部落的技术社群,还坚 持把自己收集到的资料整理成Gopher日报,此外,也在GopherChina这 样的技术大会上做过主题演讲。目前,中文社区内最好的Go语言入门教
程《Tony Bai·Go语言第一课》就出自白明之手。 如果由一个既有丰富实战经验又有丰富分享经验的人来写一本Go语 言的进阶书,这会是Go社区的幸运,而你手上的就是这样一本书。 这本书完全符合我对一本进阶书的定义,在这里你会看到Go语言的 生态,你会了解到关于写好Go项目的种种知识。如果说这本书有什么缺 点,那就是它太厚了,不过,这恰恰是白明经验丰富的体现。没办法, 真实世界就是这么复杂。 如果你能坚持把这本书读完,把其中的知识内化为自己的行动,你 的Go项目开发之路将由荆棘密布变成一片坦途,对路上的种种你都会有 似曾相识的感觉。 祝你阅读愉快,开发愉快! 郑晔 《10×程序员工作法》专栏作者/前火币网首席架构师/ 前Thoughtworks首席咨询师
前言 为什么要写本书 Go是Google三位大师级人物Robert Griesemer、Rob Pike及Ken Thompson共同设计的一种静态类型、编译型编程语言。它于2009年11 月正式开源,一经面世就凭借语法简单、原生支持并发、标准库强大、 工具链丰富等优点吸引了大量开发者。经过十余年演进和发展,Go如今 已成为主流云原生编程语言,很多云原生时代的杀手级平台、中间件、 协议和应用都是采用Go语言开发的,比如Docker、Kubernetes、以太 坊、Hyperledger Fabric超级账本、新一代互联网基础设施协议IPFS等。 Go是一门特别容易入门的编程语言,无论是刚出校门的新手还是从 其他编程语言转过来的老手,都可以在短时间内快速掌握Go语法并编写 Go代码。但很多Go初学者的疑问是:Go入门容易,但精进难,怎么才 能像Go开发团队那样写出符合Go思维和语言惯例的高质量代码呢?这 个问题引发了我的思考。在2017年GopherChina大会上,我以演讲的形 式初次尝试回答这个问题,但鉴于演讲的时长有限,很多内容没能展 开,效果不甚理想。而本书正是我对解答这个问题所做出的第二次尝 试。 我这次解答的思路有两个。 思维层面:写出高质量Go代码的前提是思维方式的进阶, 即用Go语言的思维写Go代码。 实践技巧层面:Go标准库和优秀Go开源库是挖掘符合Go 惯用法的高质量Go代码的宝库,对其进行阅读、整理和归 纳,可以得到一些能够帮助我们快速进阶的有效实践。 本书正是基于以上思路为想实现Go精进但又不知从何入手的你而写 的。 首届图灵奖得主、著名计算机科学家Alan J. Perlis曾说过:“不能影 响到你的编程思维方式的编程语言不值得学习和使用。”由此可见编程 思维对编程语言学习和应用的重要性。只有真正领悟了一门编程语言的 设计哲学和编程思维,并将其应用到日常编程当中,你才算真正精通了 这门编程语言。 因此,本书将首先带领大家回顾Go语言的演进历程,一起了解Go 语言设计者在设计Go语言时的所思所想,与他们产生思维上的共鸣,深 刻体会那些看似随意实则经过深思熟虑的设计。
The above is a preview of the first 20 pages. Register to read the complete e-book.