基本信息
编辑推荐
国外*经典的Go语言*作,Go语言编程的先驱者Mark Summerfield(萨默菲尔德)的实践经验总结。
《Go语言程序设计》是一本Go语言实战指南,帮你了解Go语言,按Go语言的方式思考,以及使用Go语言来编写高性能软件。
作者展示了如何编写充分利用Go语言突破性的特性和惯用法的代码,以及Go语言在其他语言之上所做的改进,并着重强调了Go语言的关键创新。
注重实践教学,每章都提供了多个经过精心设计的代码示例。
由国内**个核心服务完全采用Go语言实现的团队——七牛团队核心成员翻译。
内容简介
计算机书籍
《Go语言程序设计》既是一本实用的Go语言教程,又是一本权威的Go语言参考手册。书中从如何获取和安装Go语言环境,以及如何建立和运行Go程序开始,逐步介绍了Go语言的语法、特性以及一些标准库,内置数据类型、语句和控制结构,然后讲解了如何在Go语言中进行面向对象编程,Go语言的并发特性,如何导入和使用标准库包、自定义包及第三方软件包,提供了评价Go语言、以Go语言思考以及用Go语言编写高性能软件所需的所有知识。
《Go语言程序设计》的目的是通过使用语言本身提供的所有特性以及Go语言标准库中一些最常用的包,向读者介绍如何进行地道的Go语言编程。《Go语言程序设计》自始至终完全从实践的角度出发,每一章提供多个生动的代码示例和专门设计的动手实验,帮助读者快速掌握开发技能。《Go语言程序设计》适合对Go语言感兴趣的各个层次的Go语言程序员阅读和参考。
作译者
许式伟——七牛云存储CEO,开源爱好者,发布过十余个C++开源项目,拥有超过15年的C/C++开发经验。
吕桂华——七牛云存储联合创始人,拥有十余年的C/C++大型项目开发经验,也曾在Java和.NET平台上探索多年。
徐 立——七牛云存储首席布道师,前盛大创新院高级研究员。
何李石——七牛云存储布道师。
七牛云存储技术团队是国内第一个核心服务完全采用Go语言实现的团队。
目录
第1章 5个例子 1
1.1 开始 1
1.2 编辑、编译和运行 3
1.3 Hello Who? 6
1.4 大数字——二维切片 8
1.5 栈——自定义类型及其方法 12
1.6 americanise示例——文件、映射和闭包 18
1.7 从极坐标到笛卡儿坐标——并发 28
1.8 练习 33
第2章 布尔与数值类型 35
2.1 基础 35
2.2 布尔值和布尔表达式 39
2.3 数值类型 40
2.3.1 整型 42
2.3.2 浮点类型 46
2.4 例子:statistics 53
2.4.1 实现一个简单的统计函数 54
2.4.2 实现一个基本的HTTP服务器 55
2.5 练习 58
译者序
为什么我可以如此坚定地相信,选择Go语言不会有错,并且相信Go语言会成为未来10年最流行的语言?除了Go语言的并发编程模型深得我心外,Go语言的各种语法特性显得那么深思熟虑、卓绝不凡,其对软件系统架构的领悟,让我深觉无法望其项背,处处带给我惊喜。
Go语言给我的第一个惊喜是大道至简的设计哲学。
Go语言是非常简约的语言。简约的意思是少而精。少就是指数级的多。Go语言极力追求语言特性的最小化,如果某个语法特性只是少写几行代码,但对解决实际问题的难度不会产生本质的影响,那么这样的语法特性就不会被加入。Go语言更关心的是如何解决程序员开发上的心智负担。如何减少代码出错的机会,如何更容易写出高品质的代码,是Go设计时极度关心的问题。
Go语言追求显式表达。任何封装都是有漏洞的,最佳的表达方式就是用最直白的表达方式,所以也有人称Go语言为“所写即所得”的语言。
Go语言也是非常追求自然(nature)的语言。Go不只是提供极少的语言特性,并极力追求语言特性最自然的表达,也就是这些语法特性被设计成恰如多少人期望的那样,尽量避免惊异。事实上,Go语言的语法特性上的争议是非常少的。这些也让Go语言的入门门槛变得非常低。
Go语言给我的第二个惊喜是最对胃口的并行支持。
我对服务端开发的探索,始于Erlang语言,并且认为Erlang风格并发模型的精髓是轻量级进程模型。然而,Erlang除了语言本身不容易被程序员接受外,其基于进程邮箱做消息传递的并发编程模型也小有瑕疵。我曾经在C++中实现了一个名为CERL的网络库,刚开始在C++中完全模仿Erlang风格的并发编程手法,然而在我拿CERL库做云存储服务的实践中,发现了该编程模型的问题所在并做了相应的调整,这就是后来的CERL2.0版本。有意思的是,CERL2.0与Go语言的并行编程思路不谋而合。某种程度上来说,这种默契也是我创办七牛时,Go语言甚至语法特性都还没有完全稳定,我们技术选型就坚决地采纳了Go语言的重要原因。
Go语言给我的第三个惊喜是接口。
Go语言的接口,并非是你在Java和C#中看到的接口,尽管看起来有点像。Go语言的接口是非侵入式的接口,具体表现在实现一个接口不需要显式地进行声明。不过,让我意外的不是Go的非侵入式接口。非侵入式接口只是我接受Go语言的基础。在接口(或契约)的表达上,我一直认为Java和C#这些主流的静态类型语言都走错了方向。C++的模板尽管机制复杂,但是走在了正确的方向上。C抖0x(后来的C+/11)呼声很高的concept提案被否,着实让不少人伤了心。但Go语言的接口远不是非侵入式接口那么简单,它是Go语言类型系统的纲,这表现在以下几个方面。
(1)只要某个类型实现了接口要的方法,那么我们就说该类型实现了此接口。该类型的对象可赋值给该接口。
(2)作为1的推论,任何类型(包括基础类型如bool、int、strzng等)的对象都可以赋值给空接口interface{}。
(3) 支持接口查询。如果你曾经是Windows程序员,你会发现COM思想在Go语言中通过接口优雅呈现。并且Go语言吸收了其中最精华的部分,而COM中对象生命周期管理的负担,却因为Go语言基于gc方式的内存管理而不复存在。
Go语言给我的第四个意外惊喜是极度简化但完备的面向对象编程(OOP)方法。
Go语言废弃大量的OOP特性,如继承、构造/析构函数、虚函数、函数重载、默认参数等:简化的符号访问权限控制,将隐藏的this指针改为显式定义的recelver对象。Go语言让我看到了OOP编程核心价值原来如此简单——只是多数人都无法看透。
Go语言带给我的第五个惊喜是它的错误处理规范。
Go语言引入了内置的错误(e~or)类型以及defer关键字来编写异常安全代码,让人拍案叫绝。下面这个例子,我在多个场合都提过:
f, err:=os.Open(file)
if err !=nil {
... //错误处理
前言
从语言的设计精神来说,Go语言与C语言非常相似,是一门精小而高效的语言,它有便利的底层设施,如指针。不过Go语言还提供了许多只在高级或者非常高级的语言中才有的特性,如Unicode字符串、强大的内置数据结构、鸭子类型、垃圾收集和高层次的并发支持,使用通信而非常规的共享数据和锁方式。另外,Go语言还提供了一个庞大且覆盖面全的标准库。
虽然所有的Go语言特性或者编程范式都会以完整可运行的示例来详细讲解,但是本书还是假设读者有主流编程语言的经验,比如C、C++、Java、Python或其他类似的语言。
要学好任何一门语言,使用它进行编程都是必经之路。为此,本书采用完全面向实战的方式,鼓励读者亲自去练习书中的例子,尝试着去解决练习题中给出的问题,自己去写程序,以获得宝贵的实践经验。正如我以前写的书一样,本书中所引用的代码片段都是“活代码”。也就是说,这些代码自动提取自.go源文件,并直接嵌入到提供给出版商的PDF文件中,故此不会有剪切和粘贴错误,可以直接运行。只要有可能,本书都会提供小而全的程序或者包来作为贴近实际应用场景的例子。本书的例子、练习和解决方案都可以从ww.qtrac.eu/gobook.html这个网址获得。
本书的主要目的是传授Go语言本身,虽然我们使用了Go语言标准库中的许多包,但不会试图全都涉及。这并不是问题,因为本书向读者提供了足够的Go语言知识来使用任何标准库中的包或者是任何第三方Go语言的包,当然还能够创建自己的包。为什么是Go
Go语言始于2007年,当时只是Google内部的一个项目,其最初设计者是RobertCJriesemer、 Unix泰斗Rob Pike和Ken Thompson。2009年11月10日,Go语言以一个自由的开源许可方式公开亮相。Go语言由其原始设计者加上Russ Cox、Andrew Gerrand、Ian Lance Taylor以及其他许多人在内的一个Google团队开发。Go语言采取一种开放的开发模式,吸引了许多来自世界各地的开发者为这门语言的发展贡献力量。其中有些开发者获得了非常好的声望,因此他们也获得了与Google员工一样的代码提交权限。此外,Go Dashboard这个网站(godashboard. appspot.com/project)也提供了许多第三方的Go语言包。
Go语言是近15年来出现的最令人兴奋的新主流语言。它是第一个直接面向21世纪计算机和开发者的语言。
Go语言被设计为可高效地伸缩以便构建非常大的应用,并可在普通计算机上用几秒钟即完成编译。快如闪电的编译速度可能在一定程度上是因为语言的语法很容易解析,但更主要是因为它的依赖管理。如果文件app.go依赖于文件pkgl.go,而pkgl.go又依赖于pkg2.go,在传统的编译型语言中,app.go需要依赖于pkgl.go和pkg2.go目标文件。但在Go语言中,一切pkg2.go导出的内容都被缓存在pkgl.go的目标文件中,所以pkgl.go的目标文件足够独立构建app.go。对于只有三个源文件的程序来说,这看不出什么优劣,但对于有着大量依赖关系的大型应用程序来说,这样做可以获得巨大的编译速度提升。
由于Go语言程序的构建是如此之快,因此它也适用一些本来应该使用脚本语言的场景(见“Go语言版Shebang脚本”,参见1.2节)。此外,Go语言可用于构建基于Google App Engine的Web应用程序。
Go语言使用了一种非常干净且易于理解的语法,避免了像老的语言如C++(发布于1983年)或Java(发布于1995年)一样的复杂和冗长。Go语言是一种强静态类型的语言,这在有些程序员看来是构建大型应用程序的必备特性。然而,使用Go语言进行编程并不需要像使用别的静态语言那样打太多的字,这要归功于Go语言简短的“声明并初始化”的变量声明语法 (由于编译器会推断类型,因此并不需要显式地写明),以及它对鸭子类型强大而便捷的支持。
像C和C++这样的语言,当涉及内存管理时需要程序员非常谨慎地面对,特别是对于并发程序,要跟踪它们的内存分配简直犹如噩梦,而这些本来可以交给计算机去做。近年来,C押在这方面用各种“智能”指针进行了很大的改善,但在线程库方面还一直在追赶Java。通过使用垃圾收集器,Java减轻了程序员管理内存的负担。虽然C++语言现在有一个标准的线程库,但是 C语言还只能使用第三方线程库。然而,在C、C++或Java中编写并发程序仍然需要相当地谨慎,以确保在恰当的时间正确地锁定和解锁资源。
Go编译器和运行时系统会处理这些繁琐的跟踪问题。对于内存管理而言,Go语言提供了一个垃圾收集器,因此无需使用智能指针或者手动释放内存。Go语言的并发机制基于计算机科学家C.A.R.Hoge提出的CSP(Communicating Sequential Processes)模型构建,这意味着许多并发的Go语言程序不需要加任何锁。此外,Go语言引入goroufine——一种非常轻量级的进程,可以一次性大量创建,并可跨处理器和处理器核心自动进行负载平衡,以提供比老的基于线程的语言更细粒度的并发。事实上,因为Go语言的并发支持使用起来如此简单和自然,移植单线程程序到Go时经常会发现转为并发模型的机会大增,从而可以更充分地利用计算机资源。
Go语言是一门务实的语言,与语言的纯净度相比,它更关注语言效率以及为程序员带来的便捷性。例如,Go语言的内置类型和用户自定义的类型是不一样的,因为前者可以高度优化,后者却不能。Go语言也提供了两个基本的内置集合类型:切片(slice,它的实际用途是为了提供变长功能的数组)和映射(map,也叫键值字典或散列表)。这些集合类型非常高效,并且在大多数情况下都能非常好地满足需求。当然,Go语言也支持指针(它是一个完全编译型的语言,因此在性能方面没有虚拟机挡路),所以它可以轻松创建复杂的自定义类型,如平衡二叉树。
虽然C语言仅支持过程式编程,而Java则强制要求程序员按照面向对象的方式来编程,但 Go语言允许程序员使用最合适的编程范式来解决问题。Go语言可以被用做一个纯粹的过程式编程语言,但对面向对象编程也支持得很好。不过,我们也会在后文看到,Go语言面向对象编程的方式与C++、Java或Python非常不同,它更容易使用且在形式上更加灵活。
就像C语言一样,Go语言也不支持泛型(用C++的话来说就是模板)。然而,Go语言所提供的别的功能特性消除了对泛型支持的依赖。Go并不使用预处理器或者包含文件(这也是为什么它编译得如此之快的另一个原因),因此也无需像C和C++那样复制函数签名。同时,因为没有使用预处理器,程序的语义就无法在Go语言程序员背后悄悄变化,但这种情况在C和C++下使用#define时一不小心就会发生。
可以说,C++、Objective-C和Java都试图成为更好的C语言(后者是间接地成为了更好的 C++语言)。尽管Go语言干净而轻盈的语法容易让人联想到Python,Go语言的切片和映射也非常类似于Python的列表和字典,但Go语言也可以被认为试图成为一个更好的C。然而,与任何其他语言相比,Go语言从语言本质上都更接近于C语言,并可以被认为保留了C语言的所有精华的同时试图消除C语言中的缺陷,同时加入了许多强大而有用的独有特性。
Go语言最初被构思为一门可充分利用分布式系统以及多核联网计算机优势且适用于开发大型项目的编译速度很快的系统级语言。现在,Go语言的触角已经远远超出了原定的范畴,它正被用做一个具有高度生产力的通用编程语言。使用Go语言开发和维护系统都让人感觉是一种享受。
本书的结构
第1章开始讲解如何建立和运行Go程序。这一章通过5个简短的示例简要介绍了Go语言的语法与特性,以及一些标准库。每个例子都介绍了一些不同的特性。这一章主要是为了让读者尝试一下Go语言,以此让读者感受一下学习Go语言需要学习的大致内容是什么。(这一章章还讲解了如何获取和安装Go语言环境。)
第2章至第7章更深入地讲解了Go语言的方方面面。其中有三章专门讲解了Go语言的内置数据类型:第2章涵盖了标识符、布尔值和数值类型,第3章涵盖了字符串,第4章涵盖了Go语言内置的集合类型。