选择Rust还是Go:一场编程语言的对决

发表时间: 2023-03-02 19:16

【CSDN 编者按】拥有 40 多年编程经验的知名 Go 开发者与作家 John Arundel 在其个人博客分享了《Rust vs Go in 2023》一文,该文章非常中肯地指出了这两门语言的优缺点,以及适用场景,对于那些不知道如何选择编程语言的开发者来说,绝对是一篇非常不错的参考文章。

原文地址:https://bitfieldconsulting.com/golang/rust-vs-go

未经授权,禁止转载!

作者 | John Arundel 编译 | 王子彧
出品 | CSDN(ID:CSDNnews)




今天,如果让您为您的应用程序选择最合适的编程语言的话,您会选哪个?为什么?

那么,Rust 和 Go 在性能、简单性、安全性、功能、规模等方面的比较如何?它们的共同点是什么,它们有什么根本性的不同?本文为您揭晓答案。


争论编程语言好坏,毫无意义


首先, Go 和 Rust 都是非常优秀的编程语言。它们凭借着出色的性能被广泛采用。你可能常常会看到一些文章对 Go 和 Rust 进行孰优孰劣的讨论,其实这毫无意义,每一种编程语言都代表了一定的权衡和取舍。不同的编程语言都会对不同内容进行针对性的优化,选择最合适的语言,才能事半功倍。

本文将告诉你什么时候选择使用 Go 合适,什么时候使用 Rust 会更好,并且会告诉大家两种编程语言的本质,即 Go 和 Rust 的道。虽然它们在语法和风格上有很大的不同,但 Rust 和 Go 都是构建软件的一流工具。


Go、Rust:相同之处


Rust 和 Go 共同点很多,因此经常被放在一起讨论。那么,这两种语言的共同目标是什么?

Rust 是一种低级静态类型的多范式编程语言,专注于安全和性能。

——Gints Dreimanis

然而

Go 是一种开源的编程语言,可以轻松地构建简单、可靠和高效的软件。

——Golang.org

  • 内存安全

Go 和 Rust 都是现代化的编程语言,它们的首要任务是内存安全。开发者在对 C 和 C++ 等传统语言长期使用来看,不安全或不正确地访问内存是造成错误和安全漏洞的最大原因之一。

虽然 Rust 和 Go 在处理内存安全方面的方式不同,但目标一致,他们致力于在内存管理方面超越其它语言,帮助开发者写出正常和高性能的应用程序。

  • 快速、紧凑的可执行文件

基于两者都是编译型语言,程序可以直接被翻译成可执行的机器代码,并且作为一个单一的二进制文件来部署;与 Python 和 Ruby 此类解释型语言不同,我们不需要将解释器、大量的库以及依赖关系和程序一起分发,这是一个它们较为突出的优势。因此,相比于解释型语言,使用 Rust 和 Go 编写的程序更快。

  • 通用语言

Rust 和 Go 都是可扩展性强的通用编程语言。它们可以开发各种现代软件,不管是从网络应用到分布式微服务,还是从嵌入式微控制器到移动应用程序,都可以实现。

它们都拥有优秀的标准库和高效的第三方生态系统、巨大的商业支持和庞大的用户基础。Rust 和 Go 历史悠久,并且未来几年内仍会继续被广泛使用。因此,学习 Go 或 Rust,不失为一种对时间和精力的合理投资。

  • 实事求是的编程风格

这两种语言都不是主要的函数式语言(Scala 或 Elixir),也不是完全面向对象的语言(Java 和C#)。相反,虽然 Go 和 Rust 都有与函数式和面向对象编程相关的特性,但它们都是务实的编程语言,旨在以最合适的方式解决问题,而不是强迫采用特定的方法。一般来说,如果你喜欢函数式编程风格,你会在 Rust 中发现更多的设施。

我们可以争论什么是 "面向对象 "语言,但实际上,C++、 Java 或 C# 用户所期望的面向对象的编程风格在 Go 和 Rust 中都不存在。

——Jack Mott

  • 规模化的发展

不管是大型团队、大型代码库还是两者兼具,Rust 和 Go 的部分优势决定了它们更适合于这些大型编程。例如,多年来,C 语言程序员一直在争论将括号放在哪里,以及代码应该用制表符还是空格缩进,而 Rust 和 Go 通过使用标准的格式化工具(Go 为gofmt,Rust 为rustfmt)和规范化的风格自动重写代码,完全解决了这些问题。这并不是说这种特殊的风格本身有多好:而是 Rust 和 Go 的程序员都很欣赏这种标准化的做法。

gofmt 的风格没有人喜欢,但 gofmt 是所有人的最爱。

——Rob Pike

两种语言得分很高的另一个领域是构建管道。两者都有出色的内置高性能标准构建和依赖性管理工具;不再需要与复杂的第三方构建系统搏斗,也不再需要每隔几年就学习一个新的系统。

在我的职业生涯早期,以 Java 和 Ruby 为背景的 Go 和 Rust 代码构建让我承受。当我在谷歌遇到用 Go 编写的服务时,却觉得很欣慰,因为我知道它很容易建立和运行。Rust 也是如此,尽管我只在较小的规模上工作过。我希望可无限配置的构建系统的时代已经过去了,所有语言都会有自己专门的构建工具,开箱即可使用。

——Sam Rose


Rust 还是 Go?


两者都是精心设计的优秀编程语言。但仍有很多人对 " Go 与 Rust "大惊小怪,甚至在社交媒体上大打出手,写长篇博文说只有傻瓜才会使用 Rust,或者 Go 不是真正的编程语言等。

究其缘由或许是这种行为方式会让他们自我感觉良好,但毫无意义。那些试图为你决定项目使用哪种语言,或者告诉你应该学习哪种语言来推进你的编程生涯的声音,都不会影响到一个明智的人做出重要的选择。

  • Go 与 Rust 的性能对比

Go 和 Rust 都能生成非常快的程序,因为它们不需要通过解释器或虚拟机,直接被编译成了本地机器代码。

然而,Rust 的性能特别出色。它可以与 C 和 C++ 相媲美,这两种语言通常被认为是性能最高的编译语言。但与这些传统语言不同的是,Rust 不仅提供了内存安全和并发安全,而且 Rust 还能够创建复杂的抽象。更为重要的是,Rust 使用的都是零成本抽象。

相比之下, Go 的程序性能也非常不错,它主要是为开发速度(包括编译)而设计的,而不是执行速度。Go 程序员倾向于重视清晰的代码而不是快速的代码。

Go 编译器也不会花很多时间去尝试生成最有效的机器代码;它更关心的是快速编译大量代码。所以在运行时基准测试中, Rust 通常更胜一筹。

Rust 运行时性能始终如一且可预测的,因为它不用垃圾回收。而 Go 的垃圾收集器非常高效,并且经过优化,使其 STW 的时间尽可能短(每个新的 Go 版本都在缩短)。但是垃圾收集器不可避免地在程序的行为方式中引入了一些不可预测的因素,这在某些应用中可能是一个严重的问题,例如嵌入式系统。

因为 Rust 旨在让程序员完全控制底层硬件,所以有可能实现将 Rust 程序优化到非常接近机器的最大理论性能。因此,Rust 以非凡的执行速度胜过所有其他考虑因素的领域,比如游戏编程、操作系统内核、网络浏览器组件和实时控制系统。

  • 简单性

如果没有人能弄清楚如何使用编程语言,那么速度再快也毫无用处。Go 语言是为了应对 C++ 等语言不断增长的复杂性而特意设计的,它的语法、关键字、功能都非常少。

学习 Go 语言不需要用很长时间,就可以用它写出可用的程序。

Go 非常容易学习。我知道这是一个经常被吹捧的优点,但我真的很惊讶于自己能够如此迅速地提高工作效率。多亏了这个语言、文档和工具,我只用了两天就写出了有趣的、可用的代码。

——一个Rust程序员对Go的早期印象

这里的关键词是简单。当然,简单并不等同于容易,只是小而简单的语言比大而复杂的语言更容易学习。做事的方式并没有太多不同方式,所以所有写得好的 Go 代码往往看起来都一样。

在我的代码俱乐部视频系列中,我从 GitHub 上半随机地挑选 Go 项目,并与一群 Go 初学者一起探索,看看我们究竟能理解多少代码。结果往往都比我们预期的要多。

虽然核心语言很小,但 Go 的标准库却非常强大。因此,我们不仅仅需要学 Go 语法,也需要学习需要的标准库的部分。同时,将功能从语言中转移到标准库中,能够让我们更加专注。

Go 是基于大规模的软件开发而设计的,包括大型代码库和大型团队。因此,为了能够让新手开发者尽快上手,Go 社区重视简单、明了、常规、直接的程序。

使用 Go,你可以快速完成工作。Go 是我所使用过的最有成效的语言之一。它的口号是:今天解决实际问题。

——Matthias Endler

  • 特点

Rust 相比其他几种编程语言,兼容性更强。因此,你可以用它实现更多。

——Devathon

Rust 是专门为帮助程序员用最少的代码做最多的事情而设计的,功能性强。例如,Rust 的匹配功能可以让你相当简洁地写出灵活、富有表现力的逻辑。

关于 Rust ,最开始我们有很多需要学习的地方。但其实在 C++ 或 Java 中也有很多东西要学,而且你不会获得 Rust 的高级特性,比如内存安全。

因为 Rust 表现力强,功能多,所以有人批评 Rust 是一种复杂的语言。在许多情况下,这正是我们所需要的编程语言。

Rust 为程序员准备了更复杂的语法和语义(以及可能更高的可读性成本),以换取最大可能的性能,因此会与 C++ 和 D 争取思想共享

——Dave Cheney

虽然 Rust 汲取了 Go 的一些特点,Go 也如此(尤其是泛型),但可以说 Rust 的特点更复杂,而 Go 的特点相对简单。

  • 并发性

大多数语言都对并发编程提供某种形式的支持(一次执行多项操作),但是 Go 是专为这项工作而设计的。Go 不使用操作系统线程,而是提供了一个轻量级的替代方案:goroutine。

每个 goroutine 是一个独立执行的 Go 函数,Go 调度器会将其映射到其控制下的一个 OS 线程之一。因此,调度程序只需使用有限的 OS 线程,即可非常有效地管理大量并发的 goroutine。

Go 是高规模并发应用程序的最佳选择,可实现在一个程序中运行数百万个并发的 goroutine,并且不会产生严重的性能问题,如网络服务器和微服务。

Go 的快速、安全和高效,可以让 goroutines 更好地通信和共享数据。同时,Go 的并发支持设计体验也很不错。

一般来说,对并发程序进行推理是很难的。在任何语言中建立可靠、正确的并发程序无疑是一个挑战。但是 Go 一开始就内置于语言中,因此它的并发编程是最简单、最完整的。

利用并发性的优势建立一个很好的应用程序,再部署一组微服务,对于 Go 来说轻而易举,而对于 Rust 来说并非易事。在某些方面,Rust 对防止与内存有关的安全漏洞的痴迷意味着程序员必须不遗余力地执行那些在其他语言(包括 Go)中会更简单的任务。

——Sonya Koptyev

相比之下,Rust 中的并发是一个很新的特性,并且还有待稳定中,但是它的发展非常活跃,因此请留意这块。例如,Rust 的 rayon提供了一种非常优雅且轻巧的方法,可以将顺序计算转换为并行计算。

轻量级的 Goroutine 和 Channel 语法确实很棒,彰显了语法的威力,即如此小的细节使并发编程比其他语言感觉更好。

——一个 Rust 程序员对 Go 的早期印象

虽然在 Rust 中实现并发程序并非易事,但 Rust 可以确保内存安全,这无疑也是一个优势。比如标准库的类:在 Go 中,你可以在访问某些东西之前忘记去获得一个 Mutex 锁,但是在 Rust中不行。

Go 鼓励并发并且在这方面优于 Rust,但这并不是说你不能在 Rust 中找到 Go 面向角色的并发性,这是留给程序员的一个练习。

——Dave Cheney

  • 安全性

基于前文阐述,我们不难看出 Go 和 Rust 都以不同的方式来避免一大类与内存管理相关的常见编程错误。但是,Rust 的安全性更强。

Rust 的编译器非常严格且学究(pedantic),对于使用的每一个变量和引用的每一个内存地址都会检查。它避免了一些未知风险。因此,并发和内存安全问题在 Rust 中是不可能的出现的。

——Why Rust?

对我来说,Rust 的关键优势是编译器支持,它不会让可能检测到的任何错误通过(说真的,这种感觉就像魔法一样)。

——Grzegorz Nosek

其实许多语言都有帮助程序员避免错误的设施,但 Rust 在这方面的优势更突出,因此可能不正确的程序甚至不会被编译。

有了 Rust,库程序员可以使用很多工具来防止用户犯错。Rust 让我们可以自信的说,我们拥有一块特定的数据,而其他东西没有。有这么多的工具来防止意外的误用。这是一种很棒的感觉。

——Sam Rose

对于 Rust 新手来说,与"借阅检查器(borrow checker)打架 "是常见现象,但在大多数情况下,它发现的问题确实是你的代码中真正的错误(至少是潜在的错误)。为了确保正确性与可靠性,它可能会迫使你从根本上重新架构你的程序,以避免遇到这些问题。

语言不会改变编程方式的核心?当你用其他语言工作时,Rust 中关于安全的课程也非常有用。

如果选择 Rust,通常是基于它能提供的保证:防止空指针和数据竞争安全性,可预测的运行时行为,以及对硬件的完全控制。如果你不需要这些功能,Rust 可能是不是你下一个项目的最佳选择。这是因为这些保证是有代价的:提升的时间。你需要改掉坏习惯,学习新概念。刚开始,你会经常和借阅检查器(borrow checker)进行很多斗争。

——Matthias Endler

你发现 Rust 的编程模型的挑战性可能取决于你以前在其他语言中所拥有的经验。Python 或 Ruby 程序员可能会发现它有限制;而其他人可能很高兴。

如果你是一个 C 或 C++ 程序员,在这些语言中花了几周的时间来寻找内存安全漏洞,你会非常欣赏 Rust。"与借阅检查器斗争 "变成了 "编译器可以检测到这个吗?"

——Grzegorz Nosek

  • 规模

当下的服务器程序由数千万行代码组成、数百甚至数千名程序员进行处理,而且每天都在更新。而 Go 语言就是为了在这种环境下工作而生的。随着系统的发展,Go 的设计考虑因素包括严格的依赖关系管理,随着系统增长的软件体系结构的适应性以及跨组件边界的鲁棒性

——Rob Pike

对于大型应用程序和分布式系统来说,执行速度不如开发速度重要:像 Go 这样刻意追求极简的语言可以减少初级开发者的启动时间,使他们更容易处理大型代码库的工作。

有了 Go,初级开发者更容易提高工作效率,作为一个中级开发人员,更难引入一些的脆弱的抽象,这将导致下一步的问题。基于此,Rust 在企业软件开发方面不如 Go 有说服力。

——Loris Cro

当涉及到大型软件开发时,清晰胜于灵活。Go 的限制性实际上使它比 Rust 等更复杂、功能更强大的语言更适合企业和大型组织。


Rust、Golang:不同之处


虽然 Rust 和 Go 都是常用的语言,但它们并不是真正的竞争对手,因为它们针对的是完全不同的使用情况。

Go 的整个编程方法与 Rust 的完全不同,适用性也不同。

基于此,让我们比较一下 Rust 与 Go 之间的主要区别。

  • 垃圾回收

"要不要进行垃圾回收 "是一个没有正确答案的问题。垃圾收集,以及一般的自动内存管理,使得开发可靠、高效的程序更加高效,对一些人来说,必不可少。

但也有人说,垃圾回收及其性能开销和停顿,使程序在运行时表现得不可预测,并引入了不可接受的延迟。

Go 与 Rust 完全不同。虽然两者都可以被模糊地描述为系统语言或 C 语言的替代品,但它们有不同的目标和应用,语言设计的风格,以及优先级。垃圾收集就是一个最明显的不同。在 Go 中使用 GC 使语言更简单、易推理。

在 Rust 中不实用 GC 会使程序更快(尤其是当你需要保证延迟,而不仅仅是高吞吐量的时候),并且可以启用 Go 中不可能实现的功能和编程模式(或者至少是在不牺牲性能的情况下)。

——PingCAP

  • Close to the metal

计算机编程的历史一直是一个越来越复杂抽象的故事,程序员在解决问题时不用太担心底层机器的实际工作情况。

因此,程序更容易编写,更容易移植。但是对于许多程序来说,对硬件的访问以及对程序执行方式的精确控制更为重要。

Rust 的目标是让程序员 "更接近金属",有更多的控制权,但 Go 抽象了架构细节,让程序员更接近问题。

两种语言都有不同的范围。Golang 在编写微服务和典型的 "DevOps " 任务方面表现出色,但它不是一种系统编程语言。Rust 对于并发性、安全性或性能很重要的任务来说更有优势;但它学习曲线更陡峭。

——Matthias Endler

  • Go 发展的最快

大多数人赞成开发速度优于软件速度或者性能。但实际上,性能也很重要。Rust 做了一些设计上的权衡,来提升执行速度。

相比之下,Go 更关注简单性,但是 Go 的构建速度是无可匹敌的,特别是大型代码库。

Rust 比 Go 快。在基准测试中,Rust 更快,在某些情况下,还能快到一个数量级。但在你选择用 Rust 写程序之前,你会发现 Go 在许多基准测试中并不落后于它,甚至比 Java、C#、JavaScript、Python 等快得多。

如果你需要的是一流的性能,那么选择这两种语言中的任何一种。如果你正在构建一个处理高负载的网络服务,你希望能够在纵向和横向上进行扩展,那么这两种语言都会非常适合你。

——Andrew Lader

  • 正确性

另一方面,如果一个程序不需要正常运行的话,它可以任意地快。大多数代码并不是为长期而写的,但有些程序的运行时间可以达到几十年。

在这种情况下,就值得在开发中多花一点时间,确保程序的正确性、可靠性。

Go 和 Rust 都旨在帮助你编写正确的程序,尽管方式不同。例如,Go 提供了一个很好的内置测试框架,而 Rust 则专注于使用其借阅检查器消除运行时的错误。

我的看法:明天将要发布的代码选择 Go,在未来五年内保持不变的代码选择 Rust。—Grzegorz Nosek

虽然 Go 和 Rust 都是任何严肃项目的绝佳选择,但让自己尽可能充分地了解每种语言及其特征是个好主意。

如果你想加快开发速度编写许多不同的服务,或者你拥有庞大的开发团队,那么 Go 是你的该选择的语言。Go 提供了一流的并发性,并且还保证内存安全,不强迫你管理每一个最后的细节。

Go 是一种高效的语言,避免让开发者陷入困境,专注于简单性和统一性。如果在另一方面,如果需要拧紧性能,那么 Rust 应该是你的选择。

——Andrew Lader

归根结底,合适的语言才是最好的。


合适的语言才是最好的


无论是 Rust 还是 Go,其实都值得我们去认真了解,甚至可以从中获得一些提升自身或工作的经验。如果你只能选择其一,那也要在将 Go 和 Rust 用于各种不同类型的大小程序之后,再做出你的选择。

想要成为一名成功的软件工程师,编程语言只是其中一步。设计、工程、架构、沟通和协作都是必不可少的。只有将这些做到了完美,不论你选择哪种语言,你都会成为一名优秀的软件工程师。

参考链接:https://bitfieldconsulting.com/golang/tao-of-go

☞科大讯飞回应薪酬回溯制度;OpenAI 宣布开放 API,可将 ChatGPT 集成到自己的产品;Godot 4.0 发布|极客头条
☞TeaTalk·Online演讲实录|读懂量子世界的应用与未来
☞ChatGPT API 低价上线,网友:用上 import openai,能开一家创业公司!