music unfamous original game design efficient software wtf
life ui algorithm fix programming

Golang 之初见

作者:trinity  Golang    2014-8-24  标签:  design  life 

最近不知怎么就注意了Golang,当它还叫Go 的时候,真是一听名字就没兴趣,无意中注意到了 goroutine 和 channel 的特性,就找了一本书看了看。动机就在于:看看和 Erlang 有什么不同。    

Golang 和 Erlang

虽然 Golang 是 Google 出品,而且制作者都是神一样的人物,出道也晚,但其完美度是不及Erlang 的。何况,现如今 Golang 的主阵地似乎仍在 web 领域,也让我大惑不解,web 领域有诸多的成熟方案,竟也有 Golang 的一席之地?

Golang 和 Erlang 的最大相似之处就在于都在语言级别内置支持并发,基于消息的 *routine 通信。不同之处当然就太多了:Erlang 是函数式语言,而Golang 是过程式语言;Erlang 是运行于虚拟机,Golang则可以静态编译为 native 代码。

但我认为Erlang 的 coroutine 会更完美一点,现在我还不知道goroutine 在跨进程,跨机器通信上会不会比coroutine更优雅。而且因为Golang 的 runtime.GOMAXPROCS(),你没有感觉到一丝不妙吗?当然可能 Golang 还处于1.3的水平。而且 Erlang 的“变量不可再次赋值”的特性也暗示着在并发方面会表现更好。

Golang 相对于 Erlang 的优势在于是传统的过程式语言,更容易被普通的玩家接受,也就是是一门“工程派语言”,而 Erlang 则充满了学院派气息,表现在:Erlang 的工程师更难找。这就影响了流行度和社区,以及第三方包的数量。注意:这是很重要的一个点,可能类似于人的基因。

Golang和C

从感觉上,Golang 更像C语言,语法,过程式,main,编译。但仍然没有C语言简洁。随便举几个例子

var num int = 3
type Student struct{
  Number,Name string
}

Golang 允许匿名函数,这应该算是动态语言的一个特性,但似乎为了让其语法更“脚本”,就有 var,type 这些关键字,有什么意义呢?在这里,我实在没感受到简洁。

Golang 比起C,在于有了GC,去掉了指针大部分操作,引入了 defer,多返回值多重赋值,支持接口,内置数组切片等。重要的是(对C程序员)支持cgo。

Golang 和面向对象类语言

没有什么相似的地方嘛,Golang不支持class,没有implement,derive,没有泛型,甚至没有函数重载....

    仅仅有一个接口,但和面向对象的接口有很大不同,就在于隐式的 implement,没有语法意义上的 implement,这就减少了依赖,书上叫“没有复杂的类图,继承树”,好吧,我认为逻辑上还是有那么一棵树,而且编译器也不见得就不用作检查。而且,调用的时候,你还是要 import 接口和实现所在的 package。换句话说:你见或者不见,依赖关系都在那里,少的,仅仅是那个 implement 关键字。

面向对象其实是一种思想,或者一种思维模式,不见得C程序员就不能“面向对象”,也就仅仅是没有在语法层面支持 class,仅此而已。

纵然如此,Golang 和面向对象派真是拥有八杆子也打不着的关系。

目前总结

Golang虽说还不错,但有几个点还是要说一下。

1,我输入 if 之后总要下意识的输入(),也可能是我的问题,但我仍固执的认为是Golang 的问题。

2,既然更像C,而且是“更好的C”,居然没有宏。

3,C编译器一般只允许变量定义在函数开始部分,而不允许出现在代码中间(这其实更浪费栈空间)。Golang更狠--不允许 import 未使用的包,不允许定义未使用的变量,否则就是编译器错误。甚至为此出了一个编辑器插件专门处理这个事情。我要说的是:这个插件本不该存在。既然编译器可以检测到这个错误,为什么不过虑掉这个包引用(别忘了Golang的静态编译),类型定义,而是给一个错误呢?

4,struct 是可以在外部定义成员函数的,类似于 javascript 的 prototype,这其实有点打乱代码逻辑的感觉,可能是为了解决C++这种需要 .h .cpp要输入2次的问题。个人暂时认为解决的不够好,javascript 的 prototype 诚然是很灵活--你可以为内置类型添加方法,但你别忘了Golang可是编译型语言啊。

5,说到编译型,Golang不支持动态库,我相信这个问题绝对有大量用户呼吁。书上说是为了解决依赖问题,但依赖不总是问题,而且有些库只有动态库。再说,有些人非常不喜欢大体积的文件。

对于这个问题,我们来看个例子,有一个叫 lime 的编辑器 https://github.com/limetext/lime,Golang 开发,要取代 sublime,结果编译需要一大堆依赖,又没有“没有依赖”的可执行文件下载(太大了吧),很尴尬,如果压根不提“解决依赖”这回事,倒是可以接受的。

6,GOPATH,设置GOPATH 可以在其目录下建立 bin pkg src 三个目录分别保存可执行文件,库,源代码,对于一个工程固然很好,如果一堆工程...官方的方法是设置多个GOPATH,谁有更好的方法请告知。

Golang 还有许多稚嫩的地方,留给了第三方包一个机会,比如单元测试不支持 assert,error没有HTTP 200 404 这种整型值。GOMAXPROCS能检测CPU但无法自适应,纵然如此,仍然期待在未来的版本中解决存在的问题,会成为一门好语言的。




唐老鸭  发布于 2015-10-27 09:15
golang有些包没有显示用到,但是必须引入 _ import .... ,如果不引入执行会报错,所以编译器不会直接过滤掉这个import
frinity  发布于 2015-10-27 12:27
@唐老鸭:的确是这样,那么在这个时候,文中所说的自动处理 import 的插件是如何工作的?我没测试,如果这时候这个插件仍然工作正常,编译器也应该可以自动过滤才对。

新一  发布于 2014-09-03 07:59
新一是非常喜欢GoLang的。
唐吉  发布于 2014-09-06 00:52
@新一:诚然是值得期待的语言