图灵社区会员 soooldier([email protected]) 专享 尊重版权 更多资源请访问稀酷客(www.ckook.com) 图灵社区会员 soooldier([email protected]) 专享 尊重版权 更多资源请访问稀酷客(www.ckook.com) 内 容 提 要 本书首先引领读者快速浏览 Go 语言的全貌,迅速消除读者对这门语言的陌生感,然后循序渐进地介绍 了 Go 语言的面向过程和面向对象的编程语法,其中穿插了一些与其他主流语言的比较以让读者理解 Go 语 言的设计动机,接着探讨了 Go 语言最为重要的并行编程方法,之后介绍了网络编程、工程管理、安全编程、 开发工具等非语法相关但非常重要的内容,最后为一系列关于 Go 语言的文章,可以帮助读者更深入了解这 门全新的语言。 本书适合所有层次的开发者阅读。 图灵原创 Go语言编程 ◆ 编著 许式伟 责任编辑 吕桂华 王军花 ◆ 人民邮电出版社出版发行 北京市崇文区夕照寺街14号 邮编 100061 网址 http://www.ptpress.com.cn 北京 等 电子邮件 [email protected] 印刷 ◆ 开本:800×1000 1/16 印张:15.25 字数:361千字 印数:1 — 4 000册 2012年 8 月第 1 版 2012年 8 月北京第 1 次印刷 ISBN 978-7-115-29036-6 定价:49.00元 读者服务热线:(010)51095186转604 印装质量热线:(010)67129223 反盗版热线:(010)67171154 图灵社区会员 soooldier([email protected]) 专享 尊重版权 更多资源请访问稀酷客(www.ckook.com) 前言:为什么我们需要一门新语言 1 1 前言:为什么我们需要一门新语言 编程语言已经非常多,偏性能敏感的编译型语言有 C、C++、Java、C#、Delphi和Objective-C 等,偏快速业务开发的动态解析型语言有PHP、Python、Perl、Ruby、JavaScript和Lua等,面向特 定领域的语言有Erlang、R和MATLAB等,那么我们为什么需要 Go这样一门新语言呢? 在2000年前的单机时代,C语言是编程之王。随着机器性能的提升、软件规模与复杂度的提 高,Java逐步取代了C的位置。尽管看起来Java已经深获人心,但Java编程的体验并未尽如人意。 历年来的编程语言排行榜(如图0-1所示)显示,Java语言的市场份额在逐步下跌,并趋近于C语 言的水平,显示了这门语言后劲不足。 2 3 4 Tiobe编程语言排行榜 5 所占的百分比(%) Java语言 C语言 6 7 时间 图0-1 编程语言排行榜① 8 Go语言官方自称,之所以开发Go 语言,是因为“近10年来开发程序之难让我们有点沮丧” 。 这一定位暗示了Go语言希望取代C和Java的地位,成为最流行的通用开发语言。 Go希望成为互联网时代的C语言。多数系统级语言(包括Java和C#)的根本编程哲学来源于 —————————— 9 ① 数据来源:http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html。 图灵社区会员 soooldier([email protected]) 专享 尊重版权 更多资源请访问稀酷客(www.ckook.com) 2 前言:为什么我们需要一门新语言 C++,将C++的面向对象进一步发扬光大。但是Go语言的设计者却有不同的看法,他们认为C++ 真 的没啥好学的,值得学习的是C语言。C语言经久不衰的根源是它足够简单。因此,Go语言也要 足够简单! 那么,互联网时代的C语言需要考虑哪些关键问题呢? 首先,并行与分布式支持。多核化和集群化是互联网时代的典型特征。作为一个互联网时代 的C语言,必须要让这门语言操作多核计算机与计算机集群如同操作单机一样容易。 其次,软件工程支持。工程规模不断扩大是产业发展的必然趋势。单机时代语言可以只关心 问题本身的解决,而互联网时代的C语言还需要考虑软件品质保障和团队协作相关的话题。 最后,编程哲学的重塑。计算机软件经历了数十年的发展,形成了面向对象等多种学术流派。 什么才是最佳的编程实践?作为互联网时代的C语言,需要回答这个问题。 接下来我们来聊聊Go语言在这些话题上是如何应对的。 并发与分布式 多核化和集群化是互联网时代的典型特征,那语言需要哪些特性来应对这些特征呢? 第一个话题是并发执行的“执行体”。执行体是个抽象的概念,在操作系统层面有多个概念 与之对应,比如操作系统自己掌管的进程(process)、进程内的线程(thread)以及进程内的协程 (coroutine,也叫轻量级线程)。多数语言在语法层面并不直接支持协程,而通过库的方式支持的 协程的功能也并不完整,比如仅仅提供协程的创建、销毁与切换等能力。如果在这样的协程中调 用一个同步IO操作,比如网络通信、本地文件读写,都会阻塞其他的并发执行协程,从而无法真 正达到协程本身期望达到的目标。 Go语言在语言级别支持协程,叫goroutine。Go语言标准库提供的所有系统调用(syscall)操 作,当然也包括所有同步IO操作,都会出让CPU给其他goroutine,这让事情变得非常简单。我们 对比一下Java和Go,近距离观摩下两者对“执行体”的支持。 为了简化,我们在样例中使用的是Java标准库中的线程,而不是协程,具体代码如下: public class MyThread implements Runnable { String arg; public MyThread(String a) { arg = a; } public void run() { // ... } public static void main(String[] args) { new Thread(new MyThread("test")).start(); // ... } 图灵社区会员 soooldier([email protected]) 专享 尊重版权 更多资源请访问稀酷客(www.ckook.com) 前言:为什么我们需要一门新语言 3 } 1 相同功能的代码,在Go语言中是这样的: func run(arg string) { // ... } 2 func main() { go run("test") ... } 对比非常鲜明。我相信你已经明白为什么Go语言会叫Go语言了:Go语言献给这个时代最好 的礼物,就是加了go这个关键字。当然也有人会说,叫Go语言是因为它是Google出的。好吧, 这也是个不错的闲聊主题。 第二个话题是“执行体间的通信” 。执行体间的通信包含几个方式:  执行体之间的互斥与同步  执行体之间的消息传递 先说“执行体之间的互斥与同步” 。当执行体之间存在共享资源(一般是共享内存)时,为 3 4 保证内存访问逻辑的确定性,需要对访问该共享资源的相关执行体进行互斥。当多个执行体之间 的逻辑存在时序上的依赖时,也往往需要在执行体之间进行同步。互斥与同步是执行体间最基础 的交互方式。 多数语言在库层面提供了线程间的互斥与同步支持,那么协程之间的互斥与同步呢?呃,不 5 好意思,没有。事实上多数语言标准库中连协程都是看不到的。 再说“执行体之间的消息传递”。在并发编程模型的选择上,有两个流派,一个是共享内存 模型,一个是消息传递模型。多数传统语言选择了前者,少数语言选择后者,其中选择“消息传 递模型”的最典型代表是Erlang语言。业界有专门的术语叫“Erlang风格的并发模型”,其主体思 6 想是两点:一是“轻量级的进程(Erlang中‘进程’这个术语就是我们上面说的‘执行体’) ”,二 是“消息乃进程间通信的唯一方式” 。当执行体之间需要相互传递消息时,通常需要基于一个消 息队列(message queue)或者进程邮箱(process mail box)这样的设施进行通信。 Go语言推荐采用“Erlang风格的并发模型”的编程范式,尽管传统的“共享内存模型”仍然 被保留,允许适度地使用。在Go语言中内置了消息队列的支持,只不过它叫通道(channel)。两 7 个goroutine之间可以通过通道来进行交互。 软件工程 8 单机时代的语言可以只关心问题本身的解决,但是随着工程规模的不断扩大,软件复杂度的 不断增加,软件工程也成为语言设计层面要考虑的重要课题。多数软件需要一个团队共同去完 成,在团队协作的过程中,人们需要建立统一的交互语言来降低沟通的成本。规范化体现在多 个层面,如: 9 图灵社区会员 soooldier([email protected]) 专享 尊重版权 更多资源请访问稀酷客(www.ckook.com) 4 前言:为什么我们需要一门新语言  代码风格规范  错误处理规范  包管理  契约规范(接口)  单元测试规范  功能开发的流程规范 Go语言很可能是第一个将代码风格强制统一的语言,例如Go语言要求public的变量必须以 大写字母开头,private变量则以小写字母开头,这种做法不仅免除了public、private关键 字,更重要的是统一了命名风格。 另外,Go语言对{ }应该怎么写进行了强制,比如以下风格是正确的: if expression { ... } 但下面这个写法就是错误的: if expression { ... } 而C和Java语言中则对花括号的位置没有任何要求。哪种更有利,这个见仁见智。但很显然 的是,所有的Go代码的花括号位置肯定是非常统一的。 最有意思的其实还是 Go 语言首创的错误处理规范: f, err := os.Open(filename) if err != nil { log.Println("Open file failed:", err) return } defer f.Close() ... // 操作已经打开的f文件 这里有两个关键点。其一是defer关键字。defer语句的含义是不管程序是否出现异常,均 在函数退出时自动执行相关代码。在上面的例子中,正是因为有了defer,才使得无论后续是否 会出现异常,都可以确保文件被正确关闭。其二是Go语言的函数允许返回多个值。大多数函数 的最后一个返回值会为error类型,以在错误情况下返回详细信息。error类型只是一个系统内 置的interface,如下

pdf文档 [图灵原创].Go语言编程

专业资料 > IT/计算机 > 计算机软件及应用 > 文档预览
245 页 0 下载 330 浏览 3.0分
温馨提示:当前文档最多只能预览 20 页,若文档总页数超出了 20 页,请下载原文档以浏览全部内容。
本文档由 woyaoziliao 于 2020-12-18上传分享
相关精品文档