基本信息
- 原书名:The Go Programming Language

编辑推荐
《C程序设计语言》的作者Kernighan教授与谷歌Go开发团队核心成员Donovan联合编写。凝聚大师毕生造诣,融合Go开发团队智慧,经典与权威的碰撞,打造Go语言编程圣经。尽得《C程序设计语言》的精髓,简洁实用,字字珠玑,学习Go语言程序设计的权威指南。
内容简介
计算机书籍
艾伦A.A.多诺万、布莱恩W.柯尼汉*的《Go程序
设计语言(英文版)》是所有想要学习Go语言的程序员
的**学习资源和教程,旨在帮助你立刻开始使用Go
,以及良好地掌握这门语言,并充分地利用Go语言的
特性和标准库来撰写清晰的、符合习惯用法的、高效
的程序,以解决现实世界的问题。作者不要求读者了
解Go语言或已经具有任何具体程序语言的编程经验。
所以无论你是用像C、C++或Java那样的编译型语言编
过程序,还是有过像Pyttlon、RIJby或JavaScript
那样的解释型语言的编程经历,都会觉得这本书易于
理解和学习。
本书的组织结构
·第1章介绍Go语言的基础概念,通过十几个完
成日常任务(包括读写文件、格式化文本、创建图像
。以及在Internet客户端和服务器之间通信)的程序
来介绍这门语言。
·开始的几章覆盖Go程序的组成元素(语法、控
制流、数据类型),以及程序的组织(包、文件和函数
)。后面的几章详细解释了包机制,以及如何高效地
利用go工具来构建、测试和维护项目。
作译者
艾伦A.A.多诺万(Alarl A.A.Donovarl)
谷歌公司Go开发团队成员。他拥有剑桥大学和麻省理工学院计算机科学学位,从1 996年开始就在工业界从事软件研发和编程工作。2005年起,他开始在谷歌公司工作,从事基础架构项目研发。是谷歌软件构建工具Blaze的联合设计师。他还创建了用于Go程序静态分析的许多库和工具。包括oracle、godoc-analysis、eg和gorename布莱恩W.柯尼汉(Brian W.Kerrlighan)
普林斯顿大学计算机科学系教授。他是《C程序设计语言》的作者之一,与C语言的发明人Dennis Ritctlie共同合作了这本书。1969~2000年期间,他是贝尔实验室计算机科学研究中心技术团队的成员,与LJNIX的创造者Kerl Thompsorl以及DenrIis Ritcl"Iie一起工作,同时他也是开发LJNIX的主要贡献者。他是AWK和AMPt一编程语言的作者之一,AWK中的K说的就是Kerrdghan。他还是《程序设计实践》的合著者之一。
目录
1.1 Hello,World
1.2 命令行参数
1.3 查找重复行
1.4 GIF动画
1.5 获取一个URL
1.6 并发获取多个URL
1.7 实现一个Web服务器
1.8 杂项
第2章 程序结构
2.1 名字
2.2 声明
2.3 变量
2.4 赋值
2.5 类型声明
2.6 包和文件
2.7 作用域
第3章 基本数据类型
3.1 整数
3.2 浮点数
前言
Go形成构想是在2007年9月,并于2009年11月发布,其发明人是Robert Griesemer、Rob Pike和Ken Thompson,这几位都任职于Google。该语言及其配套工具集意在使得编译和执行都能够富有表达力和效率,而且使得程序员能够轻松写出可靠、健壮的程序。
Go和C从表面上看起来相似,而且和C一样,它也是一种专业程序员使用的工具,兼有事半功倍之效。但是Go远不止是C的一种升级版本。它从多种其他语言中借用和改造了不少好的思想,还避开了那些导致复杂和脆弱的语言特性。它为并发提供的设施是全新的、高效的,它实现数据抽象和面向对象的途径是极其灵活的。它还提供了自动化的内存管理,或称为垃圾收集。
Go特别适用于构建基础设施类软件(如网络服务器),以及程序员使用的工具和系统等。但它的的确确是一种通用语言,而且在诸多领域(如图像处理、移动应用和机器学习)中都能发现它的身影。它在很多场合下被用于替换无类型的脚本语言,这是由于它平衡了表达力和安全性:Go程序通常比动态语言程序运行速度要快,遭遇意料之外的类型错误而导致的崩溃更是少得多。
Go是个开源项目,所以其编译器、库和工具的源代码是所有人皆可免费取得的。来自全世界的社区都在积极地向这个项目贡献代码。Go的运行环境包括类UNIX系统—Linux、FreeBSD、OpenBSD和Mac OS X,还有Plan 9和Microsoft Windows。只要在这些环境之一中写了一个程序,那么基本上不加修改就可以运行在其他环境中。
本书旨在帮助你立刻开始使用Go,以及良好地掌握这门语言,并充分地利用Go的语言特性和标准库来撰写清晰的、符合习惯用法的、高效的程序。
Go的起源
和生物学物种一样,成功的语言会繁衍后代,这些后代语言会从它们的祖先那里汲取各种优点;有时候,语言间的混血会产生异常强大的力量;在一些罕见情况下,某个重大的语言特性也可能凭空出现而并无先例。通过考察语言间的影响,我们可以学得不少知识,比如语言为什么会变成这个样子,以及它适配过哪些环境,等等。
下图展示了更早出现的程序设计语言对Go产生的最重要影响。
Go有时会被称为“类C语言”或“21世纪的C”。从C中,Go继承了表达式语法、控制流语句、基本数据类型、按值调用的形参传递、指针,但比这些更重要的是,继承了C所强调的程序要编译成高效的机器码,并自然地与所处的操作系统提供的抽象机制相配合。
可是,Go的家谱中还有其他祖先。产生主要影响的是来自Niklaus Wirth设计的、以Pascal为发端的一个语言支流。Modula-2启发了包概念。Oberon消除了模块接口文件和模块实现文件的区隔。Oberon-2影响了包、导入和声明语法。Object Oberon则提供了方法声明语法。
另一支Go的世系祖先,也是使得Go相对于当下的程序设计显得卓然不群者,是一族名不见经传的、在贝尔实验室开发的研究用语言。这些语言都受到了Tony Hoare于1978年发表的关于并发性基础的开创性论文所提出的通信顺序进程(Communicating Sequential Process,CSP)的启发。在CSP中,程序就是一组无共享状态进程的并行组合,进程间的通信和同步采用信道完成。不过,Hoare提出的CSP是一种形式语言,仅用以描述并发性的基本概念,并不是一种用来撰写可执行程序的程序设计语言。
Rob Pike等人开始动手做一些实验,尝试把CSP实现为真正的语言。第一种这样的语言称为Squeak(“和鼠类沟通的语言”),它是一种用以处理鼠标和键盘事件的语言。紧接着它的是Newsqueak,它带来的是类C的语句和表达式语法,以及类Pascal的类型记法。它是一种纯粹的函数式语言,带有垃圾收集,同样也以管理键盘、鼠标和窗口事件为目标。信道成了一等值(first-class value),它可以动态创建并采用变量存储。
Plan 9操作系统将这些思想都纳入了一种称为Alef的语言。Alef尝试将Newsqueak改造成一种可用的系统级程序设计语言,但垃圾收集的缺失使得它在处理并发性时太过痛苦了。
Go中的其他结构也会在这里或那里显示出某些并非来自祖先的基因。例如,iota多多少少有点APL的影子,而嵌套函数的词法作用域则来自Scheme(以及由之而来的大部分语言)。在Go语言中,也可以发现全新的变异。Go的创新性的切片为动态数组提供了高效的随机访问的同时,也允许旧式链表的复杂共享机制。还有,defer语句也是Go中新引入的。
Go项目
所有的程序设计语言都反映了其发明者的程序设计哲学,这其中往往有相当大的一部分是对于此前的语言已知缺点的应对措施。Go这个项目也是诞生于挫败感之中的,这种挫败感来源于Google的若干遭遇了复杂性爆炸性增长的软件系统。(而这个问题绝非Google所独有的。)
“复杂性是以乘积方式增长的。”Rob Pike如是说。为了修复某个问题,一点点地将系统的某个部分变得更加复杂,这不可避免地也给其他部分增加了复杂性。在不断要求增加系统功能和选项以及配置,还要快速发布的压力之下,简单性往往被忽视了—尽管长期来看,简单性才是好软件的不二法门。
要实现简单性,就要求在项目的一开始就将思想浓缩至本质,并在项目的整个生命期多保持一些自律,认识到哪些变化是好的,哪些是坏的或致命的。只要投入足够的努力,好的变化就既可以实现目的,又能够不损害软件设计上的Fred Brooks所谓的“概念完整性”。坏的变化就做不到这一点,而致命的变化则会牺牲“简单性”而去换得其浅薄的兄弟概念—“方便性”。但是,只有通过设计上的简单性,系统才能在增长过程中保持稳定、安全和自洽。
Go项目不仅仅包括语言本身、它的工具和标准库,还有决不能忽视的一点,就是它保持极端简单性的行为文化。在高级语言中,Go出现得较晚,因而有一定后发优势,它的基础部分实现得不错:有垃圾收集、包系统、一等函数、词法作用域、系统调用接口,还有不可变的、默认用UTF-8编码的字符串。但相对来说,它的语言特性不多,而且不太会增加新特性了。比如说,它没有隐式数值类型强制转换,没有构造或析构函数,没有运算符重载,没有形参默认值,没有继承,没有泛型,没有异常,没有宏,没有函数注记,没有线程局部存储。这门语言成熟而稳定,并且保证兼容更早版本:在旧版本的Go语言中写的程序,可以在新版本的编译器和标准库下编译和运行。
书摘
A program may contain multiple declarations of the same name so long as each declaration is in a different lexical block. For example, you can declare a local variable with the same name as a package—level variable. Or, as shown in Section 2.3.3, you can declare a function parameter called new, even though a function of this name is predeclared in the universe block. Don't overdo it, though; the larger the scope of the redeclaration, the more likely you are to surprise the reader.