├── .gitignore ├── Makefile ├── README.md ├── SUMMARY.md ├── book.ini ├── cover.svg ├── images ├── golang-1.svg ├── hetong-gopl-zh.jpg ├── oscollege-logo.svg └── video-001.png ├── index.md ├── preface.md └── src ├── ch1.md ├── chapter_1.1.md ├── chapter_1.2.md ├── chapter_1.md └── chapter_2.md /.gitignore: -------------------------------------------------------------------------------- 1 | /book/ 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # go install github.com/wa-lang/wabook@latest 2 | 3 | default: 4 | -@make clean 5 | wabook serve 6 | 7 | build: 8 | -rm book 9 | wabook build 10 | -rm book/.gitignore 11 | -rm -rf book/.git 12 | 13 | deploy: 14 | -@make clean 15 | wabook build 16 | -rm book/.gitignore 17 | -rm -rf book/.git 18 | -rm -rf book/examples 19 | 20 | cd book && git init 21 | cd book && git add . 22 | cd book && git commit -m "first commit" 23 | cd book && git branch -M gh-pages 24 | cd book && git remote add origin git@github.com:chai2010/gopl-notes-zh.git 25 | cd book && git push -f origin gh-pages 26 | 27 | clean: 28 | -rm -rf ./book 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go语言圣经读书笔记 2 | 3 | 4 | 5 | - Go圣经: [https://gopl-zh.github.io](https://gopl-zh.github.io) 6 | - Go圣经读书笔记: [https://github.com/chai2010/gopl-notes-zh](https://github.com/chai2010/gopl-notes-zh) 7 | - 开源学堂: [Go圣经读书笔记](https://golang.beta.oscollege.net/os/gopl-notes-zh) 8 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | [Go圣经读书笔记](index.md) 4 | [前言](preface.md) 5 | 6 | - [第1章 入门](./src/ch1.md) 7 | - [Chapter 2](./src/chapter_2.md) 8 | -------------------------------------------------------------------------------- /book.ini: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["chai2010"] 3 | description = "" 4 | language = "zh" 5 | src = "." 6 | title = "Go圣经读书笔记" 7 | 8 | [output.html] 9 | git-repository-icon = "fa-github" 10 | git-repository-url = "https://github.com/chai2010/gopl-notes-zh" 11 | edit-url-template = "https://github.com/chai2010/gopl-notes-zh/edit/master/testdata/{path}" 12 | -------------------------------------------------------------------------------- /cover.svg: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Go语言进阶系列 19 | 20 | 21 | 22 | 23 | 24 | Go圣经读书笔记 25 | 26 | 27 | Go圣经出版十年纪念 28 | 29 | 30 | 31 | 柴树杉 著 32 | 33 | 34 | 40 | 41 | 43 | 44 | 45 | 47 | 48 | -------------------------------------------------------------------------------- /images/golang-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/hetong-gopl-zh.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chai2010/gopl-notes-zh/fef9968c43f5bd9efe10778c995140da8b72e156/images/hetong-gopl-zh.jpg -------------------------------------------------------------------------------- /images/oscollege-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /images/video-001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chai2010/gopl-notes-zh/fef9968c43f5bd9efe10778c995140da8b72e156/images/video-001.png -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | ![](cover.svg) 2 | 3 | - Go圣经: [https://gopl-zh.github.io](https://gopl-zh.github.io) 4 | - Go圣经读书笔记: [https://github.com/chai2010/gopl-notes-zh](https://github.com/chai2010/gopl-notes-zh) 5 | - 开源学堂: [Go圣经读书笔记](https://golang.beta.oscollege.net/os/gopl-notes-zh) 6 | -------------------------------------------------------------------------------- /preface.md: -------------------------------------------------------------------------------- 1 | # 前言 2 | 3 | 开始认真学习Go语言是2010年开始和国内社区同学参与翻译Go语言文档的翻译工作。同时对于如何将C语言生态接入Go语言是特别关注的一个方向。在2011年初参与了深圳的一个Go语言Meetup,我提交了一个CGO的分享,在分享会上见到了将CGO移植到Windows的国内大佬韦京光老师。后来基于CGO我还包装了OpenCV,写了几个边缘检测和视频运动物体跟踪的例子。一晃这些都是15年前的事情了。 4 | 5 | 到了2012年Go1发布前后,Go语言的QQ群里已经非常热闹了,大家每天都在争论Go语言的各种语言的细节,很多人都变成了Go语言律师的角色,国内Go语言的项目和图书都慢慢多起来了。我也开始通过CGO和protorpc将Go和日常的C/C++开发工作联系了起来。同时鉴于文档翻译带来的同步问题改造了一个多语言版本的godoc,这是对Go语言的语法树最早的尝试,也为后来编撰《Go语言定制指南》和凹语言的工作带来了很多帮助。与此同时,我有意无意地期待Go语言升级级别的官方图书的出现。 6 | 7 | 到了2015年真的看到了《Go圣经》的确切的消息,并在同年10月在英文版出版后第一时间找到了电子版本(然后在亚马逊买到了英文原版的纸质版)。我是C语言圣经的忠实粉丝,在拿到Go圣经之后除了第一时间开始研读,也在想何时能够有中文版本出现。虽然我当时算是国内外最早一批Go语言粉丝,但是从来没有想到过能够参与Go圣经的翻译工作,当时也不知道任何和圣经的中文版引进相关的消息。有一天QQ群里有个同学说为什么不能自己翻译,一时冲动下就和群里的小伙伴(相互并不认识)起了圣经翻译的项目。然后4个主要翻译者,在2个月多内完成全部的翻译,是除英文外第一个完成翻译的语言。没想到Go圣经面试都差不多快十年了。 8 | 9 | Go圣经的Github仓库很快收到了4-5千个Star,但同时也在12月8号就收到了标题为“请立即停止侵权并删除侵权内容”的邮件并在邮件附上了出版社的翻译合同(当时的翻译工作刚刚过半): 10 | 11 | ``` 12 | (1)我社(XXXX出版社)经培生教育集团(Pearson Education,Inc)授权取得《The go programming language》一书中文简体版的翻译权和专有出版权,为该书中文简体版的合法权利人; 13 | (2)https://github.com/golang-china/gopl-zh链接中,你未经许可擅自翻译该书并在平台上上传的行为已经侵犯了我社的翻译权和专有出版权; 14 | (3)请收到函件后立即停止侵权,删除侵权内容。 15 | 16 | XXXX出版社,xxxx@email 17 | 2015-12-8 18 | ``` 19 | 20 | ![](images/hetong-gopl-zh.jpg) 21 | 22 | 23 | 第一次收到这类邮件有点发懵(前一个相似的经历是2010年前后,有人在出版的图书里抄袭我在网上发表的文章,我都没敢伸张),在和Go语言QQ群里小伙伴商讨后给出了以下的答复: 24 | 25 | ``` 26 | 1. 首先恭喜贵社获取 《The go programming language》一书的中文简体版专有出版权. 27 | 28 | 2. 我是从 亚马逊中国 正规渠道购买的正版的 Pearson Education,Inc 出版的 《The go programming language》一书英文版. 29 | 目前我在用这本书学习 Go语言编程 和 英文翻译. 30 | 31 | Go语言我是从 2010 年开始接触学习, 并一直在整理和翻译了一些Go语言相关的文档和资料. 32 | 英文则是从初中开始学习, 以后也会持续下去. 该读书笔记 并不是专门针对 贵社的 行为. 33 | 它只是我个人的学习Go语言和英语过程的自然延续, 并非用于商业目的. 34 | 35 | 根据国家相关的法律(为个人学习、研究或者欣赏,使用他人已经发表的作品), 36 | 我个人学习 Pearson Education,Inc 出版的 《The go programming language》 英文版, 37 | 是非商业的学习行为, 是合法的. 38 | 39 | 贵社从 Pearson Education,Inc 购买中文简体版权 和 我个人 从 Pearson Education,Inc 购买 40 | 一本英文教程都是合法的, 是两个独立的事件, 我也无意针对贵社, 因此 侵权 一说无从谈起. 41 | 42 | 我想 贵社出于商业目的购买版权并计划出版的行为, 并不能剥夺我个人学习Go语言和英语的自由. 43 | 44 | 3. 虽然我的学习方式/过程/结果 可能会对贵社产生一定的影响, 贵社以购买版权为由说我侵权的行为 45 | 同样也对我对Go语言和英文的学习产生了一定的影响. 46 | 47 | 但是本着相互理解, 解决问题的原则, 我已将读书笔记的内容该为繁体中文, 而且托管非中国范围的网站. 48 | 49 | 贵社获取的是 中国范围 中文简体版专有出版权, 我的学习笔记是在 非中国范围 网站临时托管, 非中文简体, 50 | 因此, 两者并无交集. 51 | 52 | 如果对贵社产生的影响, 我个人表示遗憾. 如果贵社对 Go语言 和 英文 有何心得或问题, 欢迎继续沟通! 53 | ``` 54 | 55 | 当时确实担心会面临法律的问题,而且仓库在同一时间也被投诉被Github平台锁定关闭了。通过申诉说明我们没有商业的利益,同时表示仓库只有中文的翻译,是用于学习的非商业行为,最早仓库被解锁了。但是几个翻译同学的胆子确实被吓破了,我们专门写了一个程序将翻译转位繁体中文版本,翻译的标题也改成了“Go语言圣经读书笔记”(也就是现在这本书的名字)。不过比较庆幸的是大家顶住了压力在2016年初完成了翻译的工作。 56 | 57 | 我觉得Go圣经翻译的风波可以算是国内IT内图书出版领域的一个有一定代表性的事件,国内的一线爱好者和从业者开始逐渐走向前台开始参与并主导IT图书的出版。在此之前,工作在一线的码农同学们很少参与写书之类的工作,而且出版社在争夺《Go圣经》之类图书的翻译版权时甚至也不会考虑QQ群里的爱好者们的想法。因为传统出版社和社区之间的沟通的障碍导致了这个事件的发生。这是一个好的现象,我们国内的Gopher终于开始慢慢影响这个行业的一些事情。 58 | 59 | 受侵权风波的影响,Go圣经翻译完成后大家也没有多大的积极性,总算是翻篇的感觉。后来也和人民邮电的杨海玲老师合作出版过几本Go语言相关的图书,听她说当时差点就能拿到Go圣经的翻译授权,如果真的是那样后面可能就是另外的故事了。 60 | 61 | 这个事情到现在也快10年,Go语言本身也有了几个较大的变化书中有些内容有点过时了,最近在从新翻阅纸质版本的《Go程序设计语言》,真的想记录一些读书笔记。刚好 [开源大学堂·Go圣经读书笔记](https://golang.beta.oscollege.net/os/gopl-notes-zh) 邀请开设一个Go语言课程,就有了这个前言。 62 | 63 | 以上这就是这个书的诞生背景。 64 | 65 | -------------------------------------------------------------------------------- /src/ch1.md: -------------------------------------------------------------------------------- 1 | # 第1章 入门 2 | 3 | 在C语言版本的圣经第1章,包含的C语言的基本语言控制流、函数等特性,其中最复杂的例子是统计单词数(是一个简单版的`wc`程序)。而Go语言圣经第1章则包含了图像动画、请求网页内容和构建一个Web服务。当然第一例子必须是万年不变的“你好,世界”。 4 | 5 | ## 1.1 你好,世界 6 | 7 | 自从C语言圣经面世起,“你好世界”就成了大多数编程语言教程的第一个例子。Go圣经的作者之一正是同为C语言圣经的作者之一 Brian W. Kernighan,因此不存在抄袭或借鉴一说。 8 | 9 | ```go 10 | package main 11 | 12 | import "fmt" 13 | 14 | func main() { 15 | fmt.Println("Hello, 世界") 16 | } 17 | ``` 18 | 19 | 作为一个老Gopher在10年后从新审视这个程序,似乎依然有一点点的陌生感觉。其中的`pacakge main`看起来有一点点的多余,其他部分的代码则从字面就能猜出个大概。当然,读者需要对UNIX那套黑话缩写有一点点了解,比如`fmt`可能表示format格式化的意思,比如`func`可能是function函数的缩写,再比如`Println`是什么鬼————哦,原来是Print+line的缩写。 20 | 21 | 圣经原文不仅仅解释了包的概念,还引入了`goimports`等工具(我还是喜欢`go fmt ./...`)。总体而言1.1节才是真正的入门,该例子的真正目的是验证Go语言工具链可以正常工作。因此必须要在命令行成功通过`go`命令执行该程序才算功德圆满。 22 | 23 | 该例子最好的体验是终于不需要处处写分号了。第一次看到部分不写分号的语言是JS,当然其中的规则也很魔幻。Go语言虽然基因里有分号,但是表象上分号的功能尽量让位于换行了。这一节没有习题,甚好! 24 | 25 | ## 1.2 命令行参数 26 | 27 | 在1.1的例子中,最难的不是理解程序,而是需要命令行完成编译和执行的全过程。对于不熟悉命令行环境的同学来说,“命令行”和“参数”这2个概念都是比较难以理解的。UNIX之父汤普森曾说进程有生命,而执行中的命令就是一个进程或生命,UNIX系统日常就是通过输入一行行的命令来执行或启动程序的: 28 | 29 | ``` 30 | $ cd 31 | $ ls 32 | $ pwd 33 | $ go 34 | ``` 35 | 36 | 命令行自己也是一个程序,对应Windows下的cmd程序,或者是类UNIX下的某种Shell外壳子程序(比如常见的bash)。这些cmd或Shell大概类似于用户和操作系统核心的代理人,让命令行用户能够通过`cd`/`ls`/`pwd`/`go`这些命令的名字来启动对应的程序。等等,这么命令的名字是什么鬼?名字是计算机世界的重要概念,和日常世界意义我们通过给某种对象或程序取个阿猫阿狗的名字。比如`cd`可能是change directory的缩写表示切换当前目录(目前就行游戏世界中的地图),比如`ls`可能是list files的缩写表示列出当前目录房间的物品(当然不包含还没有打开的箱子),比如`pwd`可能是print work directory的缩写(表示查看出当前房间的名字)。特别是这些命令在Windows命令行可能还有不同的名字,当然最后一个`go`是表示Go语言的编译器命令在所有平台都是一样的。 37 | 38 | 进程或者是命令既然有生命,那么外界怎么样和它沟通呢?先不考虑一问一答这种交互式的对话,如何一次性地获得外界的信号是很多程序关心的。比如命令行参数就是UNIX的一个发明,甚至已经成了固化到C语言的main函数的基因。此外还有读取操作系统的环境变量、读取特定路径下配置文件,读取操作系统的注册表等。看看C语言的main函数: 39 | 40 | ```c 41 | int main(int argc, char *argv[]) { 42 | return 0; 43 | } 44 | ``` 45 | 46 | 其中main函数的输入参数就是对于命令行的参数,比如 `go run main.go`命令有3个单词,对应的`argc`为3、对应的argv就是3个单词的字符串。C语言main函数的返回值对应进程的返回值。换成Go语言版本的模拟如下: 47 | 48 | ```go 49 | func main(args []string) int { 50 | return 0 51 | } 52 | ``` 53 | 54 | 但是这个main函数到底是谁来负责调用,其参数是怎么从命令行的参数转化为了程序中的参数的?这是一个根本性的大问题,直击进程的生老病死周期,当然这些工作命令行程序和命令程序通过紧密无间的配合帮我们处理好了。既然都处理好了,看看Go语言又怎么继续简化的: 55 | 56 | ```go 57 | // C程序的main函数, 是进程的入口函数 58 | int main(int argc, char *argv[]) { 59 | // 填充同一个进程/程序内的,Go语言定义的 os_Args 全局变量 60 | // 然后调用 Go 语言的 main 函数 61 | return 0; 62 | } 63 | 64 | // os 包定义的 Args 字符串列表 65 | var os.Args []string 66 | 67 | // Go语言的main函数,并不是进程执行的第一个入口函数 68 | // 前面还有很多准备工作和很多 init 函数被执行 69 | func main() { 70 | fmt.Println(os.Args) 71 | } 72 | ``` 73 | 74 | 既然`os.Args`就表示命令行参数,该节的全部内容都是围绕该变量处理。因为它是表示命令行参数的字符串列表,对应Go语言的字符串切片。因此又衍生出围绕切换的循环处理。第一个实现最具代表性: 75 | 76 | ```go 77 | // Echo1 prints its command-line arguments. 78 | package main 79 | 80 | import ( 81 | "fmt" 82 | "os" 83 | ) 84 | 85 | func main() { 86 | var s, sep string 87 | for i := 1; i < len(os.Args); i++ { 88 | s += sep + os.Args[i] 89 | sep = " " 90 | } 91 | fmt.Println(s) 92 | } 93 | ``` 94 | 95 | 细节不做展开,简单说说其中的len函数设计哲学。内置的len函数计算切片、数组、map等元素的个数,有点泛型函数的意思。在有效语言中,会通过`.size()`类似的方法来实现类似的功能。Go语言设计的一个约定和C语言差不多,内置的基础类型就是纯数据没有方法,对于一些共性的操作通过全局的内置函数实现,有点“数据+函数=程序”的意思。当然,Go对于自己定义的新类型是可以定义方法的,当然方法自然有了隐含上下空间的意思,让用户博闻强记住每个不同上下文空间的方法可不是个好的思路。 96 | 97 | 本节虽然有3个练习题,但是这里依然不想给出答案。一个建议是大家可以尝试将上述的程序,根据不同的习题要求重新封装为相对通用的函数,看看能否自己实现那些看起来更加傻瓜又强大的辅助函数。简言之,从上面的程序中能够找出多少构建`strings.Join`函数需要的材料? 98 | 99 | -------------------------------------------------------------------------------- /src/chapter_1.1.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chai2010/gopl-notes-zh/fef9968c43f5bd9efe10778c995140da8b72e156/src/chapter_1.1.md -------------------------------------------------------------------------------- /src/chapter_1.2.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chai2010/gopl-notes-zh/fef9968c43f5bd9efe10778c995140da8b72e156/src/chapter_1.2.md -------------------------------------------------------------------------------- /src/chapter_1.md: -------------------------------------------------------------------------------- 1 | # Chapter 1 2 | 3 | Image: `![](../images/video-001.png)`: 4 | 5 | ![](../images/video-001.png) 6 | -------------------------------------------------------------------------------- /src/chapter_2.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chai2010/gopl-notes-zh/fef9968c43f5bd9efe10778c995140da8b72e156/src/chapter_2.md --------------------------------------------------------------------------------