我发现我花了四年时间锤炼自己用 C 语言构建系统的能力,试图找到一个规范,可以更好的编写软件。结果发现只是对 Go 的模仿。缺乏语言层面的支持,只能是一个拙劣的模仿。
这是云风在博客中说过的一句话。最近开始做一个很有意思的个人项目,我们选择使用 Go 来搭建后台服务,Why Go ?其实真相是:不是我们选择了 Go ,是 Go 面向我们,选择了我们。
出身
首先 ,不得不说一下 Go 的作者(仅选了三个代表):
- Ken Thompson
- Rob Pike
- Robert Griesemer
Ken Thompson 大家肯定不陌生,设计了 B 语言和 C 语言,Unix 之父,1983年图领奖得主,Ken 老爷子在2000年的时候离开了贝尔实验室,转行飞行员!!!后来加入了 Google,顺手写了个 Go 。 这里 有 Ken 和他的好基友 Denise M. Ritchie的故事。
上面应该有一张 Ken 和 Denise 的合照,如果显示不出来,你可能被墙了,自救吧
Rob Pike 参与 Plan9 和 Inferno 操作系统开发,Unix 小组成员。
Robert,曾协助制作Java的HotSpot编译器和Chrome浏览器的JavaScript引擎V8。
按照这个配置,Go 出身于 Google,师出名门加上牛逼哄哄的作者们,语言界的富二代。
语言的设计者,很大程度决定了语言的设计哲学。在学习 Go 的过程中,你会感觉到这门语言如此的简洁优雅,但是又不简单。
设计哲学和特性
来说一下语言的设计哲学和特性(并不想拆开讲解)。
少即是多。跟 C++ 不同的是, Go 没有尽可能多的包含所有的特性,这只会增加了语言自身的复杂性,提高了学习成本。Go 尽可能保持简单,甚至摒弃了继承这一特性。使用过 Java 的程序员对此可能略感不适,毕竟在面向对象的编程模型中,继承是非常常用的策略。而 Go 选择使用简单的组合的方式来构建复杂的类型,因为继承会提高软件开发的复杂程度,以 Java 的集合类为例,多少学习 Java 的人至今仍然道不出集合类之间的继承关系。多用组合,少用继承,Go 放弃了看似强大的语言特性,把这一理念实践的非常彻底。
编码规范。有些人觉得代码规范被设计到语言本身会很奇怪,限制了语言。但实际上,Go 直接在语言层面加以约束,意义重大。曾几何时,团队会因为语言的 code style 而争论不休,code format 需要团队通过政策来约束,code review 可能也会因为代码格式的问题而争吵的面红耳赤。Go 作为互联网时代的一门语言,可以让全世界的 Go programmer 的代码风格保持一致,减少了无意义的争论,对于共享和合作意义重大。
设计规则灵活。Go 是一门多范式的编程语言。Go 开发者可以自由发挥。
面向接口编程。这也是大型软件系统的一种设计哲学,面向抽象,而非面向实现。Go 的接口是duck类型,鸭子类型在 ruby 中非常常见。它讲述的是如果一只鸟走起路来像鸭子,游泳也像鸭子,叫起来也像鸭子,那么这只鸟就是鸭子。因此 Go 的接口定义是隐式的,非侵入性的。它关注的不是对象(当然在 Go 中我们称之为 struct )的类型本身,而是如何使用。
异常处理和防御性编程。非常明显的一点是 Go 的函数调用对 error 的检查,虽然让代码可能并不美观,但是为了实用性,这种级别的代码防御也是可以接受的,减少不安全的代码。
实践理念。Go 自身提供了丰富的 CLI,几乎涵盖了整个软件的生命周期,例如开发,测试,部署,维护等环节。写 Go 的时候,不再需要额外的IDE或者是工具在组织代码,构建,编译,测试。这省去了很多麻烦,节省了开发者宝贵的时间。我们只需要关注代码本身即可。
以上主要是关于 Go 的设计哲学,其中掺杂的提到了一些特性。其实 Go 还有很多特性值得我们去思考 Go 为何这样设计,比如:与 C 语言的集成 CGo 这种语言间的交互性;匿名函数和闭包;函数多返回值;丰富的类型系统;自动的 gc( gc 的鼻祖应该是 lisp, 被 Java 发挥的炉火纯青,v8 因有优秀的 gc 性能得以大幅度提升,虽然这不是 Go 的专利,但是这却让开发者省了不少心);包管理;单元测试规范;并发和分布式;开发和执行效率;同样的支持跨平台;对网络开发有非常好的支持,不需要使用框架也可以很快的开发一个 web 程序。这些特性很多都不是 Go 的专利,但是 Go 却有限的进行了吸收和发挥。
总之,Go 被称为21世纪的 C 语言名副其实,正因如此,在我们的新项目中,不管是从语言本身,团队协作,部署成本,性能等各个方面考虑,Go 是我们的不二选择,当然,Go 开发者现在并不是很多(比如相对于烂大街的 Java),但是我有理由相信,越来越多的人也会像我一样,被 Go 所吸引,并且也选择 Go 。