初识Go语言
本章将简要介绍Go语言的发展历史和关键的语言特性,并引领读者对Go语言的主要特性进行一次快速全面的浏览,让读者对Go语言的总体情况有一个清晰的印象,并且能够快速上手,用Go语言编写和运行自己的第一个小程序。
语言简史
提起Go语言的出身,我们就必须将我们饱含敬意的眼睛投向持续推出惊世骇俗成果的贝尔实验室。贝尔实验室已经走出了多维诺贝尔获奖者,一些对于现在科技至关重要的研究成功,比如晶体管、通信技术、数码相机的感光元件CCD和光电池等都源自贝尔实验室。该实验室在科技界的地位可想而知,是一个毫无争议的科研圣地。
这里我们重点介绍一下贝尔实验室中一个叫计算科学研究中心的部门对于操作系统和编程语言的贡献。回溯到1969年,肯·汤普逊(Ken Thompson)
和丹吉斯·里奇(Dennis Ritchie)在贝尔实验室的计算科学研究中心开发出Unix这个大名鼎鼎的操作系统,还因为开发Unix而衍生出一门同样赫赫有名的编程语言–C语言。对于很大一部分人而言,Unix就是操作系统的鼻祖,C语言也是计算机课程中最广泛使用的编程语言。Unix和C语言在过去的几十年以来已经早就了无数的成功商业故事,比如曾在90年代如日中天的太阳微系统(Sun MicroSystems),现在正如日中天的苹果的Mac OS X操作系统其实也可以认为是Unix的一个变种(FreeBSD)。
虽然已经取得了如此巨大的成就,贝尔实验室的这几个人并没有因此沉浸在光环中止步不前,他们从20世纪80年代又开始了一个名位Plan 9的操作系统研究项目,目的就是解决Unix中的一些问题,发展出一个Unix的后续操作系统。在之后的几十年中,该研究项目又演变出另一个叫Inferno的项目分支,以及一个名位Limbo的编程语言。
Limbo是用于开发运行在小型计算机的分布式应用的编程语言,它支持模块化编程,编译期和运行时的强类型检查,进程内基于具有类型的通信通道,原子性垃圾收集和简单的抽象数据类型。它被设计为:即便在内有硬件内存保护的小型设备上,也能安全运行。
Limbo语言被认为Go语言的前身,不仅是因为同一批人设计的语言,而是Go语言确实是从Limbo语言中继承了众多优秀的特性。
贝尔实验室后来经历了多次的动荡,包括肯·汤普逊(Ken Thompson)在内的Plan 9项目的原班人马加入了Google。在Google他们创造了Go 语言。早在2007年9月,Go语言还是这帮大牛的20%自由时间的实验项目。幸运的是,到了2008年5月,Google发现了Go语言的巨大潜力,从而开始全力支持这个项目,让这批人可以全身心投入Go语言的设计和开发工作中。Go语言的第一个版本在2009年11月正式对外发布,并在此后的两年内快速迭代,发展迅猛。第一个正式版本的Go语言与2012年3月28日正式发布,让Go语言迎来的第一个引人瞩目的里程碑。
基于Google对开源的一贯拥抱态度,Go语言也自然而然的选择了开源方式发布,并使用BSD授权协议。任何人可以查看Go语言的所有源码,并可以为Go语言发展而奉献自己的力量。
Google作为Go语言的主推者,并没有简简单单的把语言推给了开源社区了事,它不仅组建了一个独立的小组全职开发Go语言,还在自家的的服务中逐步增加对Go语言的支持,比如对于Google有战略意义的云计算平台GAE(Google AppEngine)很早就开始支持Go语言了。按目前的发展态势,在Google内部,Go语言有逐渐取代Java和Python主流地位的趋势。在Google的很多产品中,我们将看到Go语言的踪影,比如Google最核心的搜索和广告业务。
按照已经发布的Go语言的特性,我们有足够的理由相信Google推出此门新编程语言绝不仅仅是简单的跑马圈地运行,而是为了解决切实的问题。
下面我哦们开看看 Go语言的主要作者。
- 肯·汤普逊(Ken Thompson):设计了B语言和C语言,创建了Unix和plan 9操作系统,1983年图灵奖得主,Go语言的共同作者。
- 罗布·派克(Rob Pike):Unix小组成员,参与Plan 9和Inferno操作系统,参与limbo和Go语言的研发,《Unix编程环境》作者之一。
- 罗伯特·格里泽默(Robert Griesemer):曾协助制作Java的HotSpot编译器和Chrome浏览器的JavaScript引擎V8.
- 伊安·泰勒(Ian Lance Taylor):GCC社区的活跃人物,gold连接器和GCC过程间优化LTO的主要设计者,Zembu公司的创始人。
- 布拉德·菲茨帕特里克(Brad Fitzpatrick):LiveJournal的创始人,著名开源项目memcached的作者。
虽然我们这里只列出了一部分,大家已经看出这个语言开发团队空前强大,这让我们在为Go语言的优秀特性而兴奋之外,还非常看好这门语言的发展前景。
语言特性
Go语言作为一门全新的静态类型开发语言,与当前的开发语言相比具备众多令人兴奋不已的新特性。本书从第二章开始,我们将对Go语言的各个方面进行详细解析,让读者能够尽量轻松地掌握这门简洁、有趣却又强大的新语言。
这里先给大家罗列一下Go语言最主要的特性:
- 自动垃圾回收
- 更丰富的内置类型
- 函数多返回值
- 错误处理
- 匿名函数和闭包
- 类型和接口
- 并发编程
- 反射
- 语言交互性
垃圾自动回收
我们可以下看下不支持垃圾回收 的语言的资源管理方式,以下为一段C语言代码:
void foo()
{
char* p = new char[128]
... // 对p指向的内存块进行赋值
func1(p); // 使用内存指针
delete[] p;
}
各种非预期的 原因,比如由于开发者的疏忽导致最后的delete语句没有被调用,都会引发经典而恼人的内存泄露问题。假如该函数被调用的非常频繁,那么我们观察该进程执行时,会发现该进程所占用的内存会一直疯长,直至占用所有系统内存并导致程序崩溃,而如果泄露的是系统资源的话,那么后果还会更加严重,最终很有可能导致系统崩溃。
手动管理内存的另外一个问题就是由于指针的到处传递而无法确定何时可以释放该指针所指向的内存块。假如代码中某个位置释放了内存,而另一些地方还在使用指向这块内存的指针 ,那么这些指针就变成了所谓的“野指针”(wild pointer)或者“悬空指针”(dangling pointer),对这些指针进行任何的读写操作都会导致不可预料的后果。
由于其杰出的效率,C和C++语言在非常长的时间内都作为服务端系统的主要开发语言,比如Apache、Nginx和Mysql等著名的服务器端软件就是C和C++开发的。然而,内存和资源管理一直是一个让人非常抓狂的难题。服务器的崩溃十有八九就是因为不 正确的内存和资源管理导致,更讨厌的是这种内存和资源管理问题即使被发现了,也很难定位到具体的错误地点,导致无数的程序员通宵达旦调式程序。
这个问题在多年里被不同人用不同的方式试图解决,并诞生了一些非常著名的内存检查工具,比如Rational Purify、Compuware BoundsChecker和英特尔的Paraller Inspector等。从设计方法的角度也衍生了类似于内存引用计数之类的方法(通常被称为“智能指针”),后续在windows平台上标准化的COM出现的一个重要原因就是为了解决内存管理的难题。但是事实证明,这些工具和方法虽然能够在一定程度上辅助开发者,但并没有让开发者避免通宵调试这样又苦又累的工作。
到目前为止,内存泄露的最佳解决方案是在语言级别引入自动垃圾回收算法(Garbage Collection),简称GC。所谓垃圾回收,即所有的内存分配动作都会被在运行时记录,同时任何对该内存的使用也都被记录,然后垃圾回收器会对所有已经分配的内存进行跟踪监测,一旦发现这些内存已经不再被任何人使用,就阶段性的回收这些没有用的内存。当然,因为需要尽量最小化垃圾回收的性能损耗,以及降低对正常程序执行过程的影响,现实中的垃圾回收算法要比这个复杂的多,比如为对象增加年龄属性等,但基本原理都是如此。