声明: 本文不是来吸引口水战的。仅仅是记录水平有限的本人的一些个人观点。Go死忠粉或者口水战爱好者勿入。

Go 是一个年轻,但是迅速蹿红的语言。我在Go刚出来的时候,出于对其创造者的崇拜,就开始关注了。然而真正使用却是这两年的事。Docker, kubernetes的出现大大加速了Go流行的速度。因为很多人是因为Go可以用来编写这样复杂度的程序开始关注它的。我相反,13年我是因为有人无意中用Go写了docker才开始关注并最终进入容器这个坑的。

先谈优点吧

  • 简单(非常)的语法。 比Go语法还简单的不多了。很多其它高级语言认为必须有的语法,如class, exception都被有意的干掉了。这样导致了学习成本的降低。很多程序猿不需要多少时间就可以上岗,并贡献有用的代码。
  • static typing。 static typing 对大型程序,尤其是大型团队还是有意义的。
  • bound checking。 安全第一,安全第一
  • 不错的tool chain。 包括各自独立的小工具,使得用Vim之类的编辑器也可以有很好的体验。编译非常快,虽然有GOPATH这个坑,但也能忍了。
  • 静态可执行文件。 这个从部署的角度来讲,比较起其它语言,如Python等等来说,太容易了。但是有时候 你还是得像C一样用特殊的命令行:

  • channel + goroutine。 其实所有的语言都可以做到这个,但是将它们提升到语法的层面确实使得这类的编程变得简单了许多。

讲优点的目的是为了更过瘾的吐槽,haha

  • 没有好用的REPL。 也许静态语言不需要吧。但我已习惯
  • 没有好用的debugger。 其实我也不怎么用debugger。但是知道有一个在那儿准备着,想起来用就可以用还是很好的。delve? 装了N次都没法成功。
  • 没有generic。 这个被人说烂了。这玩意对于动态语言没必要,但是静态语言就。。。
  • 有些脑残的gofmt。 比如自动对齐等号。这个有点自相矛盾。gofmt强制在数组,或者列表的最后一个元素后面要加上逗号。这是很好的,原因是这样diff看起来会很干净。但是等号自动对齐跟这个完全是背道而驰啊。在我曾经还很年轻的时候,也喜欢把代码做这样美丽的优化,但结果是被构架师批了一顿。

另外有人知道为什么gofmt一定用不同的风格格式化下面这两段time.Duration的代码吗?
图片描述

  • C的印记很重。 Go有指针!虽然比C指针安全多了。但是我还是得懂啊。我还得知道这玩意是地址啊。错误处理也是和C基本一样一样的。整体上讲,Go感觉就是像一个改进了的C语言。不知道强制用CamelCase是不是要故意让自己和C区分一下。脑补一下,如果用C常用的this_is_a_function来写Go代码是不是就和写C没什么区别了。
  • 自动识别interface的实现。 在实现一个interface的时候,无需声明,只要默默的实现其中所有的方法即可。通常来讲,显式的总是比隐式的好。Go作者们建议尽量小的interface,这个是靠谱的。也许正因为如此,作为一个_优雅_的语言,Go不希望你写出类似这样的语句吧: struct Foo implements Writer, Reader, Formatter, Transformer, Builder。 毕竟咱不是Java。
  • package management。 为什么一定要强制绝对的import 路径?假设我clone了github/zhangsan/abc,干脆就没法编译!已无力吐槽...
  • channel没有说的那么强悍。 Robe Pike鼓励大家communicate by channel。channel + goroutine确实是不错的设计。但是只说channel, 不提sync,这就有点不厚道了。其实用了goroutine,很快就会发现,该锁的还是要锁。还是需要程序猿懂得race condition等等。
  • interface{}就像是 C 里面的 void *。对于static typing是一种侵入。
  • 创作人员的态度有点。。。精英主义。比如上面说的generic, 比如对一些语法糖的拒绝和不屑。为什么我一定要写list[len(list)-1]啊,为什么就不能有cond? a: b这样的conditional operator啊。与此同时又创造if a = foo(); a != nil {}这种几乎唯一的功能就是把一行加长的语法。
  • 几乎在鼓励写超长的行, 或者确切的说,鼓励写超长的函数名。如果你看过kubernetes的 代码,你就会看到超过80字符的代码行无处不在,我刚看到时非常惊讶。Go语言是这样要求的,你函数的开始{必须在函数名的后面,缩进必须是4个,这样的话,如果你有个非常长的函数名,你只能写在一行,否则后面的行就和函数体本身混在一起了。所以,Go基本上是在鼓励你写超长的行。这基本上在所有语言里面都是被鄙视的。我不知道Go作者么是怎么想的。
  • 名字。 无法搜索,还和另外一个语言冲突,还和围棋的英文冲突。。。。
  • camelCase 这篇文章 _find_it_is_much_easier_to_read_something_in_underscores_than_in_camel_case. ButThenAgainThatMightJustBeMe,YouShouldAllLetMeKnowWhatYouThink。但我们还是为Go的创造者找个借口吧:CamelCase能少打几个字符。。。

吐完了

无可置疑,Go是一种很实用的语言。其设计者的目的非常明确:创造一种简单易学,上手快,适合blue collar,适合开发分布式程序的语言。策略是以史上最成功的语言C为基础,改进其糟粕(内存管理,安全性,字符串),加入某些现代语言的元素。针对的受众是大型软件团队。从这些角度来讲,它无疑是成功的。但仅仅从语言角度来讲,Go有很多败笔。

写着文章的目的不是要争个谁好谁不好。而是:一来整理记录一些自己的想法;二来证明再NB的人也被他所处的环境,经历,背景,时代等等束缚;三是继续高唱~永远不做脑残粉~

最后,附几个链接:

  1. 对Go语言的综合评价

    • 王垠的评论。虽然我并不认可这人,但是这文章我还是比较认同的。
  2. go-is-not-good

    • github上面一个类似awesome XXX的一个集合。只不过是负面的连接集合。

本文固定链接: http://www.js-code.com/c/c_61914.html