Files
the-way-to-go_ZH_CN/eBook/01.2.md
2013-04-09 18:38:18 -04:00

138 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#1.2 语言的主要特性与发展的环境和影响因素
##1.2.1 影响Go语言发展的早期编程语言
正如“21世界的C语言”这句话所说Go语言并不是凭空而造的而是和C++Java和C#一样属于C系。不仅如此设计者们还汲取了其它编程语言的精粹部分融入到Go语言当中。
在声明和包的设计方面Go语言受到PascalModula和Oberon系语言的影响在并发原理的设计上Go语言从同样受到 Tony Hoare 的CSP通信序列进程 *Communicating Squential Processes*理论影响的Limbo和Newsqueak的实践中借鉴了一些经验并使用了和Erlang相同的机制。
这是一门完全开源的编程语言因为它使用BSD授权许可所以任何人都可以进行商业软件的开发而不需要支付任何费用。
尽管为了能够让目前主流的开发者们能够对Go语言中的类C语言的语法感到非常亲切而易于转型但是它在极大程度上简化了这些语法使得它们比C/C++的语法更加简洁和干净。同时Go语言也拥有一些动态语言的特性这使得使用Python和Ruby的开发者们在使用Go语言的时候感觉非常容易上手。
下图展示了一些其它编程语言对Go语言的影响
![](images/1.3.influences_on_go.jpg?raw=true)
图1.3 其它编程语言对Go语言的影响
##1.2.2 为什么要创造一门编程语言
- C/C++的发展速度无法跟上计算机发展的脚步,十多年来也没有出现一门与时代相符的主流系统编程语言,因此人们需要一门新的系统编程语言来弥补这个空缺,尤其是在计算机信息时代。
- 对比计算机性能的提升,软件开发领域不被认为发展地足够快或者比硬件发展更加成功(有许多项目均以失败告终),同时应用程序的体积始终在不断地扩大,这就迫切地需要一门具备更高层次概念的低级语言来突破现状。
- 在Go语言出现之前开发者们总是面临非常艰难的抉择究竟是使用执行速度快但是编译速度并不理想的语言C++),还是使用编译速度较快但执行效率不佳的语言(如:.NETJava或者说开发难度较低但执行速度一般的动态语言呢显然Go语言在这3个条件之间做到了最佳的平衡快速编译高效执行易于开发。
##1.2.3 Go语言的发展目标
Go语言的主要目标是将静态语言的安全性和高效性与动态语言的易开发性进行有机结合达到完美平衡从而使编程变得更加有乐趣而不是在艰难抉择中痛苦前行。
因此Go语言是一门类型安全和内存安全的编程语言。虽然Go语言中仍有指针的存在但并不允许进行指针运算。
Go语言的另一个目标是对于网络通信并发和并行编程的极佳支持从而更好地利用大量的分布式和多核的计算机这一点对于谷歌内部的使用来说就非常重要了。设计者通过 goroutine 这种轻量级线程的概念来实现这个目标,然后通过 channel 来实现各个 goroutine 之间的通信。他们实现了分段栈增长和 goroutine 在线程基础上多路复用技术的自动化。
这个特性显然是Go语言最强有力的部分不仅支持了日益重要的多核与多处理器计算机也弥补了现存编程语言在这方面所存在的不足。
Go语言中另一个非常重要的特性就是它的构建速度编译和链接到机器代码的速度一般情况下构建一个程序的时间只需要数百毫秒到几秒。作为大量使用C++来构建基础设施的谷歌来说无疑从根本上摆脱了C++在构建速度上非常不理想的噩梦。这不仅极大地提升了开发者的生产力,同时也使得软件开发过程中的代码测试环节更加紧凑,而不必浪费大量的时间在等待程序的构建上。
依赖管理是现今软件开发的一个重要组成部分但是C语言中“头文件”的概念却导致越来越多因为依赖关系而使得构建一个大型的项目需要长达几个小时的时间。人们越来越需要一门具有严格的、简洁的依赖关系分析系统从而能够快速编译的编程语言。这正是Go语言采用包模型的根本原因这个模型通过严格的依赖关系检查机制来加快程序构建的速度提供了非常好的可量测性。
整个Go语言标准库的编译时间一般都在20秒以内其它的常规项目也只需要半秒钟的时间来完成编译工作。这种闪电般的编译速度甚至比编译C语言或者Fortran更加快使得编译这一环节不再成为在软件开发中困扰开发人员的问题。在这之前动态语言将快速编译作为自身的一大亮点像C++那样的静态语言一般都有非常漫长的编译和链接工作。而同样作为静态语言的Go语言通过自身优良的构建机制成功地了去除了这个弊端使得程序的构建过程变得微不足道拥有了像脚本语言和动态语言那样的高效开发的能力。
另外Go语言在执行速度方面也可以与C/C++相提并论。
由于内存问题通常称为内存泄漏长期以来一直伴随着C++的开发者们Go语言的设计者们认为内存管理不应该是开发人员所需要考虑的问题。因此尽管Go语言像其它静态语言一样执行本地代码但它依旧运行在某种意义上的虚拟机以此来实现高效快速的垃圾回收使用了一个简单的标记-清除算法)。
尽管垃圾回收并不容易实现但考虑这将是未来并发应用程序发展的一个重要组成部分Go语言的设计者们还是完成了这项艰难的任务。
Go语言还能够在运行时进行反射相关的操作。
使用 `go install` 能够很轻松地对第三方包进行部署。
此外Go语言还支持调用由C语言编写的海量库文件第3.9节),从而能够将过去开发的软件进行快速迁移。
##1.2.4 指导设计原则
Go语言通过减少关键字的数量25个来简化编码过程中的混乱和复杂度。干净、整齐和简洁的语法也能够提高程序的编译速度因为这些关键字在编译过程中少到甚至不需要符号表来协助解析。
这些方面的工作都是为了减少编码的工作量甚至可以与Java的简化程度相比较。
Go语言有一种极简抽象艺术家的感觉因为它只提供了一到两种方法来解决某个问题这使得开发者们的代码都非常容易阅读和理解。众所周知代码的可读性是软件工程里最重要的一部分 ***译者注:代码是写给人看的,不是写给机器看的*** )。
这些设计理念没有建立其它概念之上,所以并不会因为牵扯到一些概念而将某个概念复杂化,他们之间是相互独立的。
Go语言有一套完整的编码规范你可以在 [Go语言编码规范](http://golang.org/doc/go_spec.html) 页面进行查看。
它不像Ruby那样通过实现过程来定义编码规范。作为一门具有明确编码规范的语言它要求可以采用不同的编译器如 gc 和 gccgo第2.1节)进行编译工作,这对语言本身拥有更好的编码规范起到很大帮助。
[LALR](http://en.wikipedia.org/wiki/LALR_parser) 是Go语言的语法标准你也可以在 `src/cmd/gc/go.y` 中查看到,这种语法标准在编译时不需要符号表来协助解析。
##1.2.5 语言的特性
Go语言从本质上程序和结构方面来实现并发编程。
因为Go语言没有类和继承的概念所以它和Java或C++看起来并不相同。但是它通过接口interface的概念来实现多态性。Go语言有一个清晰易懂的轻量级类型系统在类型之间也没有层级之说。因此可以说这是一门混合型的语言。
在传统的面向对象语言中,使用面向对象编程技术显得非常的臃肿,它们总是通过复杂的模式来构建庞大的类型层级,这违背了编程语言应该提升生产力的宗旨。
函数是Go语言中的基本构件它们的使用方法非常灵活。在第六章我们会看到Go语言在函数式编程方面的基本概念。
Go语言使用静态类型所以它是类型安全的一门语言加上通过构建到本地代码程序的执行速度也非常快。
作为强类型语言,隐式的类型转换是不被允许的,记住一条原则:让所有的东西都是显式的。
Go语言其实也有一些动态语言的特性通过关键字 `var`所以它对那些逃离Java和.Net世界而使用PythonRubyPhp和JavaScript的开发者们也具有很大的吸引力。
Go语言支持交叉编译比如说你可以在运行Linux系统的计算机上开发运行下Windows下运行的应用程序。这是第一门完全支持UTF-8的编程语言 ***译者注:.NET好像也支持吧*** 这不仅体现在它可以处理使用UTF-8编码的字符串就连它的源码文件格式都是使用的UTF-8编码。Go语言做到了真正的国际化
##1.2.6 语言的用途
Go语言被设计成一门应用于搭载Web服务器存储集群或类似用途的巨型中央服务器的系统编程语言。对于高性能分布式系统领域而言Go语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持这对于游戏服务端的开发而言是再好不过了。
Go语言一个非常好的目标就是实现所谓的复杂事件处理[CEP](http://en.wikipedia.org/wiki/Complex_event_processing)这项技术要求海量并行支持高度的抽象化和高性能。当我们进入到物联网时代CEP必然会成为人们关注的焦点。
但是Go语言同时也是一门可以用于实现一般目标的语言例如对于文本的处理前端展现甚至像使用脚本一样使用它。
值得注意的是因为垃圾回收和自动内存分配的原因Go语言不适合用来开发对实时性要求很高的软件。
越来越多的谷歌内部的大型分布式应用程序都开始使用Go语言来开发例如谷歌地球的一部分代码就是由Go语言完成的。
如果你想知道一些其它组织使用Go语言开发的实际应用项目你可以到这个页面进行查看[http://go-lang.cat-v.org/organizations-using-go](http://go-lang.cat-v.org/organizations-using-go)。出于隐私保护的考虑许多公司的项目都没有展示在这个页面。我们将会在第21章讨论到一个使用Go语言开发的大型存储区域网络SAN案例。
在Chrome浏览器中内置了一款Go语言的编译器用于本地客户端NaCl ***为什么我觉得这是"钠"*** 这很可能会被用于在Chrome OS中执行Go语言开发的应用程序。
Go语言可以在Inter或ARM处理器上运行因此它也可以在安卓系统下运行例如Nexus系列的产品。
在 Google App Engine 中使用Go语言2011年5月5日官方发布了用于开发运行在 Google App Engine 上的Web应用的 Go SDK在此之前开发者们只能选择使用Python或者Java。这主要是 David Symonds 和 Nigel Tao 努力的成果。目前最新的稳定版是基于r60.3的SDK 1.6.1于2011年12月13日发布。当前Go语言的稳定版本是Go 1 ***译者注目前最新的稳定版是Go1.1*** )。
##1.2.7 关于特性丢失
许多能够在大多数面向对象语言中使用的特性Go语言都没有支持但其中的一部分可能会在未来被支持。
- 为了简化设计,不支持函数重载和操作符重载
- 为了避免在C/C++开发中的一些Bug和混乱不支持隐式转换
- Go语言通过另一种途径实现面向对象设计第10-11章来放弃类和类型的继承
- 尽管在接口的使用方面第11章可以实现类似变体类型的功能但本身不支持变体类型
- 不支持动态加载代码
- 不支持动态链接库
- 不支持泛型
- 通过 `recover``panic` 来替代异常机制第13.2-3节
- 不支持断言
- 不支持静态变量
关于Go语言开发团队对于这些方面的讨论你可以通过这个页面查看[http://golang.org/doc/go_faq.html](http://golang.org/doc/go_faq.html)
##1.2.8 使用Go语言编程
如果你有其它语言的编程经历面向对象编程语言JavaC#Object-CPythonRuby在你进入到Go语言的世界之后你将会像迷恋你的X语言一样无法自拔。Go语言使用了与其它语言不同的设计模式所以当你尝试将你的X语言的代码迁移到Go语言时你将会非常失望所以你需要从头开始用Go的理念来思考。
如果你在至高点使用Go的理念来重新审视和分析一个问题你通常会找到一个适用于Go语言的优雅的解决方案。
##1.2.9 小结
这里列举一些Go语言的必杀技
- 简化问题,易于学习
- 内存管理,简洁语法,易于使用
- 快速编译,高效开发
- 高效执行
- 并发支持,轻松驾驭
- 静态类型
- 标准类库,规范统一
- 易于部署
- 文档全面
- 免费开源
##链接
- [目录](directory.md)
- 上一节:[起源与发展](01.1.md)
- 下一章:[安装与运行环境](02.1.md)