Go 还是 Rust?选 Go。
这篇文章是我很久以前写的。在此期间,我对其中一些方面的看法发生了变化。
为了提供更加平衡的优缺点视角,我建议改为阅读这篇关于 Go 与 Rust 的比较文章。这篇文章是我与 Shuttle 🚀 合作撰写的。
“Rust 还是 Go,我该选哪个?”这是我经常被问到的问题。两种语言似乎都在争夺同一批用户,而且它们似乎都是系统编程(systems programming)语言,所以一定存在一个明确的赢家,对吧?
Go:实用、务实、朴素

我不认为 Go 是一门优雅的语言。它最大的特性是简单容易上手。Go 甚至都不是一门系统编程语言。虽然它非常适合编写微服务(microservices)以及围绕后端基础设施构建的工具,但我不愿意用它来编写内核或内存分配器(memory allocator)。
但使用 Go,你可以很快地把事情做成。
Go 是我使用过的生产力最高的语言之一。它的箴言是:今天就解决现实问题。
Rust 的强大保证是有代价的

相比之下,Rust 很难。我花了好几个月才算具备一定的生产力。你需要投入大量时间,才能看到任何收益。Rust 已经是一门强大的语言,而且每天都在变得更强。对我来说,它更像是务实的 Haskell,而不是更安全的 C。
别误会:我喜欢 Rust,它也帮助我成为了更好的程序员。它确实是一门值得学习的优秀语言。真正的问题在于,它是否适合你的下一个大型项目。
问题是:如果你选择 Rust,通常是因为你需要这门语言所提供的保证:
- 防范
Null指针、竞态条件(race conditions)以及各种底层威胁的安全性。 - 可预测的运行时行为(runtime behavior)(零成本抽象(zero-cost abstractions),且没有垃圾回收器)。
- 对硬件的(几乎)完全控制(内存布局、处理器特性)。
- 与其他语言实现无缝互操作。
如果你并不需要这些特性,Rust 可能不是下一个项目的理想选择。这是因为这些保证是有代价的:上手时间。你需要摒弃一些坏习惯,并学习新的概念。刚开始时,你很可能会频繁地与借用检查器(borrow checker)斗争。
案例研究:通过试除法判断素数
假设你想检查一个数是否为素数。最简单的方法是检查这个数能否被任何比它小的自然数整除(没有余数)。如果不能,我们就找到了一个素数!这种方法称为试除法(trial division)。
下面是用 Golang 实现的方法(感谢 Rosetta Code):
func IsPrime(n int) bool {
if n < 0 {
n = -n
}
switch {
case n < 2:
return false
default:
for i := 2; i < n; i++ {
if n%i == 0 {
return false
}
}
}
return true
}下面是 Rust 中实现相同功能的代码:
pub fn is_prime(n: u64) -> bool {
match n {
0...1 => false,
_ => {
for d in 2..n {
if n % d == 0 {
return false;
}
}
true
}
}
}乍一看,两种解决方案非常相似。但仔细观察,就能发现一些区别。
- 在 Go 中,我们使用简单的 switch-case 语句。在 Rust 中,我们使用
match语句,后者强大得多。 - 在 Go 中,我们使用简单的 for 循环遍历从 2 到 n 的数字。在 Rust 中,我们使用范围表达式(
2..n)。 - 在 Go 中,我们使用两个
return语句;在 Rust 中,我们有一个return表达式。一般来说,Rust 中的大多数东西都是表达式,可以返回,也可以赋值给变量。有关表达式的更多信息,请参阅这里。
在许多方面,Rust 比 Golang 更具函数式特征。你可以使用为 Range 实现的 any 方法重写上面的代码。
fn is_prime(n: u64) -> bool {
match n {
0...1 => false,
_ => !(2..n).any(|d| n % d == 0),
}
}刚开始它可能看起来有些陌生,但过一段时间就会变得驾轻就熟。
当然,这只是一个快速示例。我建议你浏览一下 Rosetta Code 上的一些代码,以便更好地感受这两种语言。
案例研究:在文本文件中查找重复单词
如果你更喜欢直观的方式,这里有一段视频,展示了我分别用 Go 和 Rust 编写一个简单的并发程序(concurrent program),以比较这两种语言:
我更喜欢 Go 的一些方面
- 编译速度快
- 务实的问题解决方式
- 适合典型 DevOps 任务的优秀生态系统
- 开箱即用的标准库
- IDE 支持
- 简单的错误处理
- 吉祥物 😉
我更喜欢 Rust 的一些方面
- 安全性:没有空指针,没有数据竞争……
- 细粒度的系统控制
- 惊人的运行时速度(可与 C/C++ 媲美)
- zero-cost abstractions
- 棒且思想开放的社区
- 使用 cargo 进行简单的包管理
- 以 traits(特征)形式提供对 Generics(泛型)的支持
- C 互操作和 FFI
结论
99% 的时候,Go 都“足够好”;而在那 1% 不够好的时候,你会知道。然后再看看 Rust,因为这两种语言互补性很好。如果你对实践型 Rust 咨询感兴趣,请从我的日历中选择一个日期,我们可以聊聊我能如何帮助你。
归根结底,Rust 和 Go 并不是真正的竞争对手。
随机一篇博客