我在Rust之前就学会了Go,我开始的时候很喜欢它,但我越用越觉得它的缺点越多,越不喜欢它。我发现他们的很多承诺并没有真正得到证实。

后来我发现并学习了Rust,我越学越喜欢它。在我看来,它解决了我在golang中发现的很多问题。这些天来,除非有外部因素的要求,否则我不会去碰它。

但Rust的学习曲线要陡峭得多。所以如果你时间有限,而且还不了解Rust的话,它可能是更好的选择。

Go的理念都是,做任何事情都应该只有一种方法。
在学习API方面,Go是一种非常小的语言。这对于快速学习是非常好的,因为你基本上可以在一个周末阅读和学习你想要的几乎所有东西。

但在那之后,你就没有什么发展空间了。你最终会一次又一次地复制粘贴相同的模式。使用同样的一小套工具来解决每一个问题--即使这些工具并不是最适合那个特定问题的。我发现这最终导致了很多不合格的冗长的解决方案,而且你的工具箱也非常有限。

相比之下,Rust给了你更多的工具。
你确实需要花更多的时间来学习,但你可以更有选择地在何时何地使用它们。这给了你更多的自由,在你学习它们的过程中,你可以创建一些非常简明但可读的代码。这确实需要更长的时间,但一般来说,学习语言的时间与使用它的时间相比相形见绌。

我还发现golang的语言中有很多陷阱:
当我在一个团队中使用它时,我会一次又一次地发现很多内存泄漏、死锁或其他对初学者来说并不明显的问题。
有时甚至会对那些看起来像内存泄漏但实际上不是:其中很多是由于未能关闭一个打开的文件或网络套接字造成的,这在Go中是一个即时的内存泄漏(很难从一眼就看出)。

还有像go这样的东西所显示的各种模式,只是在任何没有立即关闭的程序中泄漏go例程的方法。而我已经花了相当长的时间来调试生产中的go程序的内存泄漏问题。

这实际上是你掌握这门语言的大部分时间是在尝试调试所有出错的事情,并从你过去看到的问题模式中发现潜在的问题。

我还发现很多承诺随着时间的推移而被打破:
就像错误处理,把错误当作值来对待是一件很好的事情。那么你就永远不能忘记处理错误。
因为没有任何机制可以告诉你,你没有检查错误,相反,它依赖于未使用的变量检查。
这确实能捕捉到很多错误,但也有很多无法捕捉的地方:比如根本没有分配一个变量,或者重新分配给一个你已经使用过的变量(这很常见,这样你就不会出现err、err1、err2、err3等变量)。
而默默地忽略一个错误会导致各种奇怪的问题,可能很难调试,其中我已经看到在生产代码中多次发生。

要深入了解Go作为一种语言的其他问题,这是一篇关于它的好文章:我想离开 Mr. Golang 的狂野之旅

我发现Rust解决了很多Go的这些问题。开放的文件和套接字在超出作用域时将被关闭,因此更难产生内存泄漏。
结果会被标记为必须使用,所以如果你不使用它,就会警告你。
Rusts的异步代码不容易泄露永远循环的coroutines,因为必须有东西驱动它们完成,如果它的句柄被丢弃,那么它将被正确地清理掉。

在我看来,每一个需要做出的决定:
Go语言都选择了最简单的一种方法,但最终导致了问题,而Rust选择了技术上更正确的解决方案,虽然更难实现和学习,但导致了更少的问题。