再见,Go 语言

2020-07-09 00:00:00 语言 代码 工具 风格 这是
导读:几乎每天都有很多人从某种语言切换到另一种语言,大家看看就好

在这篇文章中,我将要解释我为什么不再使用 Go 语言编程(译者注:Go 语言写的工具作者还是会使用的)。首先从我真正喜欢的 Go 的特性开始。

Go 的优点

原生支持的消息传递

Go 利用轻量级的线程以及使用消息传递进行通信的特性,是真正让我开始学习 Go 的原因。 这似乎是一个简单的从 C 语言派生的 Erlang 的替代品。虽然这种比较可能高估了 Go 的实力,但用 Go 为我公司的远程维护工具实现后端服务器来说是足够好的。这个工具在浏览器和我们公司的 board 之间充当中间人,如下图所示:

虽说实现起来比我初步预期的要复杂得多,但完成项目后,我就被 Go 所吸引了。

真正的胖二进制(通用二进制)

当我次部署我的 Go 应用程序时,我很惊讶,这是多么容易啊。只需将二进制文件上传到服务器或将其包含在容器镜像中,添加配置以及静态资源即可完成。 Go 的胖二进制文件捆绑了运行时环境,库以及应用程序都使其部署成为一种享受,不再需要复杂的运行时管理等等。

当然,你需要创建运行用户,添加防火墙异常,确保数据库备份等,但这是一次性作业,与编程无关。

也支持 BSD 和 Windows

在我公司,我们运行 Linux 和 Windows 服务器,基本上,Go 编译器在所有操作系统上的工作方式都是相同的。无论是 Windows 还是 Linux,一个简单的 `$go install <applicationName>` 命令是就是你需要在编译系统时执行的所有操作。

Go 的缺点

严格执行「Google 代码指南」

Go 编译器强制执行 Google 的 C ++ 和 Python 风格指南。例如,将一个开放的大括号放在新行将会导致编译器发出语法错误。随着 Visual Studio Code Go 插件的更新,默认情况下,自动重构已经打开,并且由于我的代码风格,Linter 显示了相当多警告,所以我把它关闭了。

在我个人看来,编程语言应该让开发者使用他/她自己的风格,对程序员风格的重大影响是 OK 的,但是一个狂热的宗教信仰般的强制是无法接受。 我的风格是我老师佳实践,以及我职业生涯中的经验,我并不想就因为 Google 的想法而完全改变。

破碎不堪的包管理

Go 「包管理器」通过直接从源代码解析依赖关系,并从本地文件系统或从使用 HTTP 的 git 仓库中提取所需的代码而有意义的工作。这在理论上是非常好的,但实际上具有破坏性的缺点,即无法确定包的版本。Go 通过简单地拉取 master 分支来解决这个问题,但如果在主分支中引入了破坏性更改,你的应用程序将无法重新编译或进行新的安装。

Kubernetes 项目显示了可能的缓解策略,其中创建者将其应用程序的依赖关系存储在其仓库中(译者注:即将依赖库的源码也放在当前库中),然而,这是使用「版本控制系统」的反模式。

没有继承

尽管有很大的争议,但我更倾向于通过使用类层级结构对对象的类似行为进行建模。Go 选择不支持这种行为,导致我写了很多重复的代码。例如,我的 SAP 分析 Web 界面使用三种不同的产品组结构,因为所需的详细信息因用户故事而异,Go 却强制我在三个不同的地方使用相同的代码。

接口有助于解决对象方法的问题,而非数据成员问题。 此外,我不喜欢接口实现的含义,因为大多数编辑者无法提供有用的建议,必须手动做很多文档查找工作。

缺失泛型

与 Ruby 和 Python 相比,处理集合感觉真的很麻烦,尽管受到后者的启发,Go 声称提供了一种动态的语言感觉。这个问题和其他问题都可以通过引入泛型来解决,但是,Go 的创作者及其社区使用非常奇怪的论据拒绝了这一点。

功能缺失的 HTTP 库

对于创建简单的回传服务来说,Go 内置的 HTTP 库很好。但是,要添加 REST 风格的参数, Cookie 或 Session,需要使用额外的插件,如 Gorilla Toolkit。如果你在寻求一个现代的HTTP库,在文档中没有提到这些遗漏的东西。

另外,设置支持的 TLS 密码也是相当麻烦的。

另一个问题是错误处理。例如,默认的 Dropwizard HTTP 客户端默认启用 GZIP 压缩,但是,Go 的 HTTP 库没有识别 GZIP 头,并试图以纯文本格式来读取压缩过的有效负载。这是导致「一小时的问题排除」的开始。

总而言之,我喜欢 Go 和它的简约编程。但是,Go 对我来说是错误的工具,不过,我将继续使用 Go 制作的工具,如 Hugo,Docker 和 Kubernetes。


相关文章