go语言sort包 go语言strconv(13)


为什么选择go
说完了python,现在来说说为什么我们选择go 。其实除了python,我们也有其他的选择,java,php,lua(openresty),但最终我们选择了go 。
虽然java和php都是最好的编程语言(大家都这么争的) , 但我更倾向一门更简单的语言 。而openresty , 虽然性能强悍,但lua仍然是动态语言,也会碰到前面说的动态语言一些问题 。最后,前金山许式伟用的go,前快盘架构师葱头也用的go,所以我们很自然地选择了go 。
go并不是完美 , 一堆值得我们吐槽的地方 。
error , 好吧,如果有语言洁癖的同学可能真的受不了go的语法,尤其是约定的最后一个返回值是error 。项目里面经常会充斥这样的代码:
if _, err := w.Write(data1); err != nil {
returun err
}
if _, err := w.Write(data2); err != nil {
returun err
}
难怪有个梗是对于一个需求,java的程序员在写配置的时候,go程序员已经写了大部分代码,但是当java的程序员写完的时候,go程序员还在写err != nil 。
这方面,errors-are-values倒是推荐了一个不错的解决方案 。
包管理,go的包管理太弱了 , 只有一个go get , 也就是如果不小心更新了一个外部库 , 很有可能就导致现有的代码编译不过了 。虽然已经有很多开源方案 , 譬如godep以及现在才出来的gb等 , 但毕竟不是官方的 。貌似google也是通过vendor机制来管理第三方库的 。希望go 1.5或者之后的版本能好好处理下这个问题 。
GC,java的GC发展20年了,go才这么点时间,gc铁定不完善 。所以我们仍然不能随心所欲的写代码,不然在大请求量下面gc可能会卡顿整个服务 。所以有时候,该用对象池,内存池的一定要用,虽然代码丑了点,但好歹性能上去了 。
泛型,虽然go有inteface,但泛型的缺失会让我们在实现一个功能的时候写大量的重复代码,譬如int32和int64类型的sort,我们得为分别写两套代码,好冗余 。go 1.4之后有了go generate的支持,但这种的仍然需要自己根据go的AST库来手动写相关的parser , 难度也挺大的 。虽然也有很多开源的generate实现,但毕竟不是官方的 。
当然还有很多值得吐槽的地方,就不一一列举了,但是go仍旧有它的优势 。
静态语言,强类型 。静态编译能帮我们检查出来大量的错误,go的强类型甚至变态到不支持隐式的类型转换 。虽然写代码感觉很别扭,但减少了犯错的可能 。
gofmt,应该这是我知道的第一个官方提供统一格式化代码工具的语言了 。有了gofmt,大家的代码长一个样了,也就没有花括号到底放到结尾还是新开一行这种蛋疼的代码风格讨论了 。因为大家的代码风格一样,所以看go的代码很容易 。
天生的并行支持,因为goroutine以及channel , 用go写分布式应用,写并发程序异常的容易 。没有了蛋疼的callback导致的代码逻辑割裂 , 代码逻辑都是顺序的 。
性能,go的性能可能赶不上c , c++以及openresty , 但真的也挺强悍的 。在我们的项目中 , 现在单机就部署了一个go的进程,就完全能够胜任以前200个python进程干的事情 , 而且CPU和MEM占用更低 。
运维部署,直接编译成二进制,扔到服务器上面就成,比python需要安装一堆的环境那是简单的太多了 。当然,如果有cgo,我们也需要将对应的动态库给扔过去 。
开发效率,虽然go是静态语言,但我个人感觉开发效率真的挺高,直觉上面跟python不相上下 。对于我个人来说,最好的例子就是我用go快速开发了非常多的开源组件,譬如ledisdb , go-mysql等,而这些最开始的版本都是在很短的时间里面完成的 。对于我们项目来说,我们也是用go在一个月就重构完成了第一个版本,并发布 。

推荐阅读