吐槽一下 Go 语言

由于公司一直都在大力推广 Go 语言,我也有幸接触了一下。虽然 Google 内部已有三大语言(C++、Java、Python),Go 在公司内部的政治意义大于它的实际使用,但它的设计却有着很多亮点。比如 Go 自带了代码格式化工具(gofmt)和自动化测试工具(go test),这些标准化的工作在其它语言中一直都存在着多方争议,一直都不能统一,而 Go 从一开始就搞定了这些琐碎问题,让广大程序员可以把重心都放在开发新程序上,而不是争一些有的没的。

当然,这篇文章并不想表扬 Go 语言,而是要吐槽一下它的缺点。

Go 的设计者有着强烈的 Unix 背景,有一些平台依赖的东西都默认甚至是强制成 Unix 的。比如 Go 语言中有一个名为“path”的包,用来操作路径,而它强制路径分隔符为“/”,而无视 Windows 中的“\”。后来估计是开发中遇到一些问题,又做了一个叫“filepath”的包,来兼容 Windows 的使用。又比如 Go 语言中对环境变量的解析,强制环境变量的标识符为“$”,而不视 Windows 中的“%”,甚至整个标准库中都找不到对“%”的处理方法。这些基本的区别都不做处理,很难想象 Go 语言在跨平台设计中有哪些更为隐藏的坑。

这还不是主要的问题。更严重的问题是,Go 语言中有过多的“私有”特性,对使用者不公平。

先来举一个 C++ 的例子,C++ 中有一些运算符,比如加减乘除,这些运算符可以使用于 C++ 的基础类型(如 int)上。基础类型是 C++ 语言本身提供的,如果运算符只能作用于基础类型,那么 C++ 也可被视为“自私”的。然而 C++ 的设计者并没有这么做,这些运算符,不仅可以用于基础类型,也可以在自定义类型中,通过重载的方式来使用,使得 C++ 中不仅两个 int 可以相加,两个 class 的实例也可以相加。这样一来,运算符对于使用者就是公平的。

而 Go 语言中,则有着很多反例。比如它的泛型:Go 的官方说法是“我们不支持泛型”,具体原因就不深入讨论了。但是,Go 语言的自有类型 map 和 channel 却是支持泛型的。这就成了一个典型的“自私”的例子。类似的例子还有 Go 语言中的 internal 包有着特殊的作用域;Go 的官方库有着极短的包名,而第三方库通常是以“github”开头的很长一串文本。

这些“私有”特性,说明 Go 语言的设计者并没有为开发人员考虑过,自己设计得爽了,却徒增了学习曲线,不利于 Go 语言的推广。如果能把这些问题解决好,Go 还是可以成为一门不错的语言的。


13 条评论 添加

        1. 直接执行也是先编译再执行的,只是编译速度非常快而已。Python 的 for 循环可以接受 generator,再加上数组的构造方式,算法写出来就千差万别了。

  1. 比较流行的语言中也就C++支持运算符重载吧,也算不上Go的缺陷;泛型是官方一直在考虑添加的,应该之后不久的版本就支持了;Go暂时没有官方的包依赖管理,这才是它目前比较大的缺点,至于使用github作为包地址,我倒觉得是个优势,省了很多事

    1. C# 和 Python 也都支持运算符重载。

      用 Github 作为地址的一个问题是 fork,fork 出来的项目还是默认引用了原先的代码,要先修改几乎所有文件中的引用,才可以正常编译。

发表评论

电子邮件地址不会被公开。 必填项已用*标注