通向Golang的捷径【1. Go 语言的起源, 特性和发展】

第 I 部分 学习 Go 语言的理由

1 Go 语言的起源, 特性和发展

1.1 起源和发展

2007 年已开始酝酿 Go 语言,2009 年出现了 Go 语言的首个公开版本, Go 的初始设计开始于 2007 年 9 月 12日, 它是 Google 公司的一个附属项目 ( 花费每个工作日 20% 的时间, 来完成的项目), 并由三个著名的软件工程师来实现, Robert Griesemer(从事于 Java HotSpot 虚拟机的研究), Rob Pike(贝尔实验室 Unix 开发组的成员, 从事于 Plan 9, Inferno 操作系统和 Limbo 语言的研究), Ken Thompson(贝尔实验室 Unix 开发组的成员,曾经开发过 C 语言,Unix 和 Plan 9 操作系统, 协助 Rob Pike 完成 UTF-8 的开发), 从 2008 年 2 月开始, Ken Thompson 已在开发对应的编译器, 以展示所需的设计理念, 它能生成 C 语言代码.

在 2008 年中,Go 语言已基本完成, 剩余的工作主要是编译器和运行时功能的实现, 同时 Ian Lance Taylor 加入开发组, 并于 2008 年 5 月构建了一个基于 gcc 的编译器.

Russ Cox 加入开发组后, 开始基于 Go 语言的开发, 并创建了 Go 语言库, 在 Go 语言中, 语言库被称为包(package), 2009 年 10 月 30 日 Rob Pike 在 Google Techtalk(Go 语言实现的应用) 上, 完成了第一次语音通话.

2009 年 11 月 10 日, Go 项目发布了 Linux 和 Mac OS X 平台的正式版本, 并包含 BSD 许可证 (即完全开源), 同年 11 月 22 日, Hector Chu 创建了第一个 Windows 移植版本.

由于 Go 语言是一个开源项目, 快速壮大的社区也加速了 Go 语言的应用和开发, 从官方版本发布后, 已有超过 200 个非 Google 的贡献者, 提交了 1000 个 Go 核心的分支源码, 在过去的 18 个月中, 已有 150 个开发者为 Go 语言提供了新代码, 这使得 Go 项目变成目前世界上最大的开源项目, 最活跃的开发组 (约为所有开发组的 2%) 都位于 Ohloh(www.ohloh.net), 从 2011 年 4 月开始, 已有 10 个 Google 雇员在 Go 语言下进行全职工作, 因此这个开源语言将实现更惊人的发展, 2010 年 Andrew Gerrand 作为项目管理者, 加入该开发组.

实际上 2010 年 1 月 8 日,Go 语言才发布了首个公共的的官方稳定版, 但在 Tiobe 排名 (编程语言的一个公认排名) 中,Go 语言的发布时间为 2009 年, 2010 年 2 月 Go 语言在 Tiobe 排名, 处于 13 位, 流行度为 1.778%.

从 2010 年 5 月开始, Go 已成为 Goolgle 后台框架的开发语言, 比如编写复杂环境下的管理程序, 并衍生出一条口号,” 吃自己的狗粮”(即是俚语, 也是谐音,dog 指 Go), Google 公司想通过自身的应用, 来证明 Go 语言的产出效率.

Go 语言的官方站点为http://golang.org/, 该站点使用了 godoc(Go 开发工具) 实现的 Google App 引擎 (提供网页内容) 以及 Python 前端, 在站点主页的下方, 给出了 Go-playground(一组有趣的 Go 应用), 其中有简单Go 代码实现的一个沙漏, 该应用也完成了编译, 即使电脑未安装 Go 语言包, 它也能在所有的浏览器中运行,以及其他的一些应用示例, 当然也包括了著名的 Hello, World!

http://code.google.com/p/go/将提供更多的语言信息, 同时可在 http://code.google.com/p/go/issues/list 页面下, 提供 Go 语言的 bug.

Go 语言使用了 logo(基于它的速度优势) 符号 =GO, 并给出了一只地鼠作为吉祥物.

Google 讨论组 Go Nuts(http://groups.google.com/group/golang-nuts/) 相当活跃, 基于一个用户问题, 每天的讨论超过十封邮件. Go 讨论组已从 Google App 引擎中分离 ( https://groups.google.com/forum/#!forum/google-appengine-go), 虽然这一举动未必有价值, 但在http://go-lang.cat-v.org/站点上, 也可获取到 Go 语言的资源, 同时可进入 irc.freenode.net 的 #go-nuts, 即 Go IRC 的官方通道. Go 项目组的官方 Twitter 账号为@go_nuts(http://twitter.com/#!/go_nuts), 以及更多人使用的 #golang. 在 Linked-in(http://www.linkedin.com/groups?gid=2524765&trk=myg_ugrp_ovr) 上, 也出现了一个工作组, 同时 Go 语言的 Wiki 页面为http://en.wikipedia.org/wiki/Go_(programming_language), Go 应用代码的搜索页面位于http://go-lang.cat-v.org/go-search. 通过 App 引擎 Go Tour(http://go-tour.appspot.com/, 本地安装可使用 go install go-tour.googlecode.com/hg/gotour), 可在你的浏览器中尝试 Go 语言.

1.2 语言的特性和内容, 以及开发新语言的理由

1.2.1 影响 Go 的编程语言

Go 语言最初的设计目标, 就定位为 21 世纪的 C 语言, 它与 C 很相似, 同时吸取了 C++, Java 和 C# 等诸多语言的优点, 比如借鉴了 Pascal/Modula/Oberon 语言的输入机制 (声明与包), 从 Limbo 和 Newsqueak 语言中, 借鉴了并发机制 (这来自于 Tony Hoare 设计的 CSP(进程的持续通讯,Communicating Sequential Processes) 原理), 并且在 Erlang 语言中, 也引入了相似的机制.

Go 是一个完全开源的编程语言, 并使用 BSD 许可证进行发布, 这意味着任何人都能在商业项目中, 免费使用Go 语言, 并对 Go 语言进行修改.

由于 Go 使用了类 C 的风格, 这对于大多数开发者来说, 并不陌生, 而相比于 C/C++, Go 却更加简单, 并能给出更简洁和清晰的结构, 同时它又包含了动态语言的特性, 这让 Python 和 Ruby 编程者感到亲切,

1.2.2 构建新语言的理由

  • C/C++ 无法解决并行计算, 在过去的十年中, 并未出现重要的系统语言, 因此需要定义一种新的系统语言, 以满足所需的计算能力.
  • 相对于计算能力, 目前软件开发的速度并不快, 同时成功率也不高 (已出现了大量的失败项目), 由于应用程序的规模越来越大, 因此出现一种新的底层语言, 可使软件的开发提升到另一个高度.
  • 在 Go 出现之前, 开发者需要在不同的语言之间进行选择, 比如执行速度快但开发低效的 C++, 或是编译速度快但执行慢的.NET 或 Java, 又或是易于编程但执行慢的动态语言, 而 Go 可提供以上三种性能,即高效快速的编译, 快速执行和易于编程.

1.2.3 Go 语言的目标

在 Go 语言的主要目标中, 包含了静态语言的高效, 快速和安全性, 以及动态语言的易用性, 以使编程成为一种乐趣, 因此 Go 语言可提供类型安全性和存储安全性, 在 Go 语言中可使用指针, 但无法实现指针的运算.

Go 语言的另一个目标 (对于 Google 的内部应用更重要) 是为网络通讯和并发应用, 提供一个良好的支持, 以获得性能更好的分布式多核机器, 其中实现了并发协程的概念, 它是一个轻量级的线程, 以及用于协程间通讯的并发通道, 同时在线程中, 可自动实现堆栈 (段堆栈) 的增量和协程的复用, 当然 Go 最重要和最强大的功能,即提升了多核与多处理器计算机的性能, 这是现有编程语言无法支持的能力.

另一个重要的功能是快速构建 (编译和链接机器码), 编译时间通常为数百毫秒到几秒, 这明显优于 C++ 项目的构建时间, 所以在 Google 的底层应用中, 广泛使用了 Go 语言, 这也导致了开发生产率的大幅提高, 以及缩短了测试代码的开发周期.

在当下的软件开发中, 依赖管理相当重要, 比如 C 语言的头文件会导致大量的编译开销, 一个大型项目的构建时间可能需要数小时, 因此快速编译需要一个严谨而清晰的依赖分析, 所以 Go 给出了自身的包模型, 它具备的清晰依赖, 可实现快速构建, 同时 Go 的包模型也可实现良好的伸缩性.

整个 Go 标准库的编译时间小于 20 秒, 而典型项目的编译时间约为半秒, 这是相当快速的编译过程, 甚至快于C 和 Fortran 语言, 快速编译也是动态语言优于 C++ 的一个方面, 但在 Go 语言中, 并不存在这个问题, 由于编译时间的大幅缩短, 使得 Go 在编译期内, 与动态语言的效率基本一致.

另外 Go 可实现与 C/C++ 兼容的原生代码, 因此它的执行速度也很快.

在 C++ 中, 内存问题 (即内存泄露) 是一个长期存在的顽疾, 而 Go 设计者提供了自动化的内存管理, 因此开发者无须负责内存管理, 由于 Go 可执行原生代码, 所以可提供运行时应用, 以执行快速高效的垃圾收集 (目前提供了一个简单的标记和清理算法), 由于垃圾收集需面对不同类型的问题, 因此很难给出一个完美的解决方案, 为了将来的并发应用, 现在应当开始着手处理该问题.

在 Go 语言中, 还实现了一个内建的运行时应用, 即反射 (reflection), 而 go install 能为外部包提供了一个易用的开发系统, 另外 Go 还兼容已有语言的软件资源, 比如 C 语言库的使用, 参见 3.9 节.

1.2.4 Go 语言的设计理念

Go 通过减少关键字 (25 个) 的方法, 以减少代码量和编码的复杂性, 期望实现一种清晰, 规律且简洁的风格,同时这种风格也能提升编译的速度, 因为关键字无须送入符号表, 也能被解析. 实现上述的要求, 相比于其他语言 (比如 Java),Go 的代码量可显著减少, 同时 Go 还有一个极简规则, 即所有操作只需一到两种方法, 以使代码更容易阅读, 而代码的可读性是软件工程中最重要的部分.

Go 语言的设计理念是不要花费精力, 去思考其他的方法, 这样也就是不会产生其他的复杂性. 在http://golang.org/doc/go_spec.html 页面中, 可查找到 Go 的完整定义, 这也是一份清晰的语言规范, 其中并未给出一个实现,比如 Ruby 规范所给出的示例, 在 Go 语言规范中, 包含实现两种编译器 gc 和 gccgo(参见 2.1 节) 的要求, 它们对于理解语言规范, 将提供巨大的帮助.

Go 的语法类型为 LALR(1), 可参考页面http://en.wikipedia.org/wiki/LALR_parser, src/cmd/gc/go.y 文件包含了对应的语法结构, 这类语法无须符号表, 也能被解析.

1.2.5 Go 语言的特性

Go 基本上是一种命令 (过程化 + 结构化) 语言, 并能实现并发功能, 基于传统语言的分析角度, 可认定 Go 并非 OO 语言, 因为它没有包含类和继承, 但是给出了接口概念, 因此 Go 可实现多态性, 由于 Go 是一种简明的类型描述系统, 同时它又保持了轻量级, 且没有层次化, 所以 Go 又被称为一种混合语言.

主流 OO 语言实现的面对对象, 都过于笨重, 通常需要构建相当大的类型层次, 因此无法实现快速编译. 而 Go中, 函数就是最小构建基础, 同时函数又具备多种用途, 第 6 章将展示 Go 具有与函数语言相同的功能.

Go 可提供静态类型, 因此它是一个安全的语言, 并能编译出原生代码, 因此具备高效的执行速度.

Go 又是一种强类型语言, 不允许隐含的类型转换 (如 casting 或 coercion), 这也是一种设计理念, 即所有情况下都保持清晰的应用.

Go 也具有一些动态语言的特性 (比如 var 关键字), 所以从 Java/.Net 转战动态语言 ( Python, Ruby, PHP 和Javascript) 的开发者, 可以尝试一下 Go.

Go 还支持交叉编译, 比如在 Linux 上开发的应用, 也能在 Windows 运行, 同时 Go 也是第一个使用 UTF-8的语言, 不光是字符串, 程序代码也是 UTF-8 格式, 所以 Go 实现了真正的国际化.

1.2.6 Go 语言的应用

Go 的最初设想是成为一种系统编程语言, 可用于开发 Web 服务器, 存储架构等功能, 以实现大型的中心服务器, 同时在某些方面, 比如高性能的分布式系统中, 已证明 Go 的生产效率高于大多数语言,Go 更容易实现大量的并发操作, 因此最适合开发游戏服务器.

CEP(复杂事件处理,Complex event processing, http://en.wikipedia.org/wiki/Complex_event_processing) 可提供大量的并发操作, 上层抽象和执行性能, 也是 Go 创建的一个优质示例, 至于互联网应用,CEP 也将是首选.

由于 Go 又是一种通用编程语言, 所以也可实现文本和前端处理, 甚至是脚本应用, 但是 Go 并不适合于实时软件, 因为存在垃圾收集和内存的自动分配.

Google 内部使用了 Go, 来面对越来越繁重的分布式应用, 比如 Google Map 的部分功能, 其他组织应用 Go的实例, 可在 http://go-lang.cat-v.org/organizations-using-go 页面下找到, 其中并未包含 Go 的所有用户, 因为很多公司都隐藏了相关信息, 同时基于 Go 创建了一个可实现云存储的网络 ((SAN) 应用, 参见 21 章的讨论.

Go 编译器已包含在 Chrome 浏览器的 Native Client(NaCl), 所以将来在 Chrome OS 的 Web 应用中, 也许可以执行原生代码,Go 不光能在 Intel 处理器上运行, 还可在 ARM 处理器上运行 (参见第 2 章), 所以也能运行于 Android OS, 比如 Nexus smartphone 应用.

2011 年 5 月 5 日发布了 Go SDK, 因此通过 Google App Engine 框架, 可实现 Web 的云处理, 这也是第一个真正能运行在 App Engine 的编译语言, 之前只有宿主 Python 和 Java app, 这些成果都归功于 David Symonds和 Nigel Tao, Go SDK 最新的稳定版本号为 1.6.1, 它基于 r60.3 的 Go 语言版本 (发布于 2011 年 12 月 13日).

1.2.7 被 Go 语言抛弃的特性

主流OO语言所包含的一些特性, 并未加入到 Go 中, 而其中的一些功能会在将来逐步添加.
• 无函数或操作符的重载: 这是为了简化设计.
• 无隐含转换: 这是一个设计要求, 以避免和 C/C++ 一样, 产生更多的 bug 和混乱.
• 无类和继承: Go 可使用其他方法, 实现 OO 设计 (参见第 10,11 章)
• 无派生类型: 通过接口 (interface) 可实现相同的功能 (参见 11 章)
• 无动态代码的载入
• 无动态库
• 无泛型 (generics)
• 无异常处理: 可使用 recover/panic, 参见 13.2,13.3 节.
• 无断言 (assertion)
• 无常态变量

Go 开发组对于上述内容的说明, 可参见 Go FAQ( http://golang.org/doc/go_faq.html).

1.2.8 Go 语言的编程

在进行 Go 语言编程时, 如果你具有其他语言的编程背景 (大多数情况下, 应该是可提供类和继承的 OO 语言,比如 Java,C#,Objective C,Python,Ruby 等), 同时期望在 Go 中, 照搬原来的设计思路, 那么很可能会掉入一个陷阱, 因为 Go 使用了不同的模型, 你之前熟悉的习惯用法, 在 Go 中无法奏效, 所以你需要从头开始, 思考Go 的编程.

如果你已经提升了一个等级, 并开始使用 Go 语言的思维方式, 来分析问题时, 通常会得到一个不同的实现方式, 由此将产生一个优雅而通用的解决方案.

发布了80 篇原创文章 · 获赞 10 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/osoon/article/details/103741218