我已经使用Go构建了广泛的应用程序已有一段时间了;同时,我听到了很多关于Rust的好消息,所以最近我决定花时间学习 Rust。两种语言虽然是为了实现不同的目标而创建的,但有许多相似之处。在过去的几个月里,我一直在做笔记,试图围绕每种语言更适合的用例进行总结。这篇文章是这项研究的结晶。我的目标是从不同的角度和不同的角度比较两种语言,以便任何人,无论其角色如何,都可以全面了解每种语言的异同。
Go和Rust都是相对较新的语言(Rust 是新出现的语言),它们试图克服对 C++ 的批评,虽然共享相似的语法,但它们的创建都考虑了不同的设计目标。
简而言之,Go旨在简化开发,使其对任何开发人员都具有吸引力和可访问性,无论他们的经验如何。它在设计时考虑了多核处理器,以简化并发程序的并行执行,同时仍被视为通用编程语言。
另一方面, Rust是一种系统编程语言,旨在解决 C++ 的内存安全问题和其他问题,同时保持 C++ 著名的惊人性能。
两者都是出色的语言,可以为并发应用程序和流处理实现出色的性能,但它们的设计目标却截然不同。在本文中,我将尝试快速概述这两种语言及其优缺点,并回顾一些真实的单词用例,在这些用例中,我们将推荐一种语言而不是另一种语言。
Go是由Google创建的,它在语法上类似于C。它的目标是通过添加内存安全、垃圾收集和结构类型来克服 C ++中存在的不安全操作。它非常容易学习和使用。它是为多核机器构建的,以最大限度地提高并发程序的并行性。它使用称为Go Routines的非常轻量级的绿色线程进行并发编程。
Go 可以快速编译为机器码,但具有垃圾收集的便利性和运行时反射的强大功能。它是一种快速、静态类型的编译语言,感觉就像是一种动态类型的解释语言。 [2]
Go的占用空间很小,但它涵盖了许多用例,例如微服务、流处理、CLI 等等。Golang 为为不同平台生成二进制文件提供了出色的支持,而无需在目标上安装 Go。由于它小巧而高效的二进制大小,非常适合打包在容器中的云原生应用程序。您的应用程序容器可以打包到一个微型容器(~8–15MB) 中,只需几秒钟即可部署,这使其成为比 JVM 语言更好的微服务选择。有关更多信息,请查看我关于在 Kubernetes 中部署 Go 微服务的文章。
超快的编译器,感觉就像是一种解释性语言。很棒的开发者体验。快速的开发过程和提高的生产力。
简单而安全,我喜欢 GO 的地方在于,通常只有一种表达问题的方式,这加快了开发、代码审查以及整个开发过程。
非常适合初级和高级开发人员。它非常容易学习和采用,因为它不需要虚拟环境。
云原生应用和 Kubernetes的完美选择。由于体积小,没有预热时间和速度。
多亏了Go Routines ,并发变得容易。
很棒的标准库,其中包括一个 Web 服务器。
GO 可用于广泛的用例: CLI、Web 应用程序、流处理等。
资源使用率低。您可以在单个服务器上运行数百万个 Go Routines。与 JVM 相比,它使用的 RAM 和 CPU 非常少,因此运行起来要便宜得多。
它不简洁,很难保持代码干燥。
太简单了,像泛型这样的基本东西在 Go 中是不可用的,尽管它们很快就会被添加。
它是一种相对较新的语言,没有多少库或教程。
依赖管理有点反直觉且难以管理,但自从添加go mod
. 好消息是,它go mod
是语言的一部分,而不是像sbt
Scala 那样的单独项目,尽管sbt
它更强大。
错误处理很麻烦。
不像 Rust 那样优雅、强大和灵活。
与C++相比有点不成熟。
CLI 和脚本:像kubectl这样的大多数 CLI 都使用 Go。
网络应用程序。由于它是高并发且不需要太多资源的,因此非常适合处理 HTTP 请求。
流应用程序。Go 可以使用 Go 例程非常快速地处理数百万个事件。它是 Scala 中 Akka 流的竞争对手。
微服务。由于体积小、速度快、监控能力强,Go 是云原生微服务的绝佳选择。
无服务器和云应用程序。Go 是无服务器功能的完美选择,尤其是在 Google Cloud 中。
Rust也是一种新 语言,它于 2006 年在Mozilla中启动,但直到 2015 年才达到第一个稳定版本。Rust 自发布以来越来越受欢迎,特别是在过去 5 年中,许多公司如AWS、微软、 Facebook、Mozilla、 Dropbox或Cloudfare。自 2016 年以来,Rust 每年都在Stack Overflow开发者调查中被评为“最喜爱的编程语言”,没有其他语言能做到这一点,因此它很受欢迎
Rust是一种多范式、通用编程语言,旨在提高性能和安全性,尤其是安全并发性。[12] [13] Rust 在语法上类似于C++,[14]但可以通过使用借用检查器来验证引用来保证内存安全。[15] Rust 在没有垃圾收集的情况下实现了内存安全,并且引用计数是可选的。[16] [17] Rust 被称为系统编程语言,除了函数式编程等高级特性外,它还提供低级 内存管理机制。—维基百科
Rust 最初的开发目的是取代C++,让开发人员更容易使用它,同时保持相同的性能水平。C++ 已经存在了将近 50 年,它用于低级编程来开发视频游戏、操作系统、实时系统等等。C 的问题在于它难以使用,尤其是它不是内存安全的,因此会产生许多最著名的错误和安全漏洞。C 开发人员需要确保程序是内存安全的,这在生产级应用程序中很难实现,这意味着在生产中经常会发现错误,从而产生巨大的问题。这些限制导致了以控制和性能为代价的垃圾收集通用语言(例如 Java)。
因此,在 Rust 出现之前,程序员必须在古老而危险的语言 (C++) 或较慢的通用语言(如 Java)之间做出艰难的选择。随着我们继续构建更大、更复杂的应用程序,垃圾收集语言在性能方面开始落后,因为它们没有从底层硬件中榨取所有的力量。随着多核处理器的引入,需要优化接近硬件的代码,以制作更快、更便宜的程序。
那么,如果 Rust 是 C++ 的替代品,我们为什么要将它与 Go 进行比较呢?好吧,在过去的 10 年里,Rust 有了长足的发展,并且创建了许多库和工具来改善开发人员的体验,让开发人员更容易使用它,并扩大了 Rust 适用的用例数量。这意味着 Rust 已经从一个小众市场取代 C++ 作为系统级编程转向能够与 Go、Python 或 Java 竞争的高性能通用语言。与 Go 相比,Rust 将性能、低资源消耗和小型二进制文件提升到了一个新的水平。
在前端,WebAssembly将 Rust 放在了聚光灯下。WebAssembly试图通过创建在浏览器上运行的高性能应用程序来克服浏览器中的 JavaScript 限制,Rust 是 WebAssembly 中的主要语言。
Rust 源代码在LLVM的帮助下被编译为本机代码,因此它在所有 LLVM 支持的平台上都可用,这使得它非常便携,但不如 C。Rust 是一个真正的开源项目,拥有一个非常强大和开放的社区这是其成功和快速扩张的关键。
由于 Rust 是一种新语言,它没有 C++ 或 Java 等其他语言的历史分量,这意味着它的设计遵循了其他语言的最佳实践和经验教训。
Rust 功能非常丰富,它具有丰富的语法和强大的构造,例如特征、强大的类型系统、闭包、泛型、集合、模式匹配、组合器、选项等,这些在其他强大的语言(如 Scala)中都可以看到。
Rust 还可以编译成一个非常小的二进制文件,比 Go 更小,因为它没有垃圾收集器。您可以在小于 10Mb 的小容器中创建 Rust 应用程序,比 Go 还小。
最重要的是,它具有开箱即用的出色工具。Cargo可能是最好的包管理器,它对单声道存储库有很好的支持。它快速、可靠且易于使用。编译器很棒,消息非常清晰,并且大多数时候它会准确地告诉您需要做什么。
我第二喜欢的功能是非常强大的零成本抽象。这意味着您可以创建抽象来开发易于使用的 API 和库,同时保持相同的性能,编译器将解析您的代码并将其转换为不会产生任何开销的高效代码。这意味着您可以使用更高级别的编程概念,如泛型、集合等,但它们不会带来运行时成本,只有编译器时间成本,因此您可以保持代码干净和干燥,同时仍然获得最佳性能。
Rust类型系统也非常强大,类似于Scala等其他语言。由于其强大的功能, Rust 支持代数数据类型(ADT)enums
,并且还支持高级模式匹配。这些特性通常只在高级函数式编程语言中可用,而 Rust 将这些高级特性带到了低级编程中。
但是将Rust与其他语言区分开来的最具创新性和独特性的 功能是所有权模型,它允许 Rust 在编译时是内存安全的,允许您编写内存安全的高效代码,而无需显式分配和取消-分配内存。
在使用 Rust 之前,您必须在负责管理内存并确保其安全的低级编程语言之间进行选择,或者使用诸如 Java 或 Go 之类的垃圾收集语言,这会导致性能下降和更大的二进制文件大小。Rust 在编译时引入了一种新的内存安全范式。
所有权是一组程序如何管理内存的规则。所有程序都必须管理它们在运行时使用计算机内存的方式。一些语言有垃圾收集,在程序运行时不断寻找不再使用的内存;在其他语言中,程序员必须显式分配和释放内存。Rust使用第三种方法:内存通过所有权系统进行管理,该系统具有一组编译器检查的规则。如果违反任何规则,程序将无法编译。所有权的任何功能都不会在您的程序运行时减慢它的速度。— — https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
简而言之,这些是规则:
Rust 中的每个值都有一个名为owner的变量。
一次只能有一个所有者。
当所有者超出范围时,该值将被删除。
有了这 3 条简单的规则,Rust 编译器就可以发挥它的“魔力”,确保你的程序是安全的,并且在生产中不会有任何意外。
虽然Go使用引入开销的垃圾收集器解决了内存安全问题,但Rust决定使用这种新模型来创建更小更快的程序。
这种新模型的主要问题是需要时间来适应它,作为开发人员,您需要花时间很好地理解这个模型以避免无休止的挫败感,这就是为什么 Rust 学习曲线远高于其他像 Go 这样的语言,但是一旦你习惯了这个新模型,你编写程序的速度几乎和其他语言一样快。
非常快速和高效。
功能丰富:闭包、模式匹配、集合、泛型等。
简洁易读。
WebAssembly支持。
Cargo是一个优秀的包管理器。与 Go 相比,依赖管理要好得多。
它与 C 兼容,可以与现有的 C 程序交互。
真正的开源与充满活力的社区。
能耗低,成本低。
出色的增长和受欢迎程度的提高。
伟大的错误处理,特别是与 Go 相比。
非常小的二进制大小,比 Go 小,因为它没有垃圾收集器。
快速编译器,但比 Go 慢一点。
资源使用率低,但这取决于您如何构建程序,但通常它会比 Go 使用更少,因为内存在程序运行时是空闲的,而不是垃圾收集器。
不成熟,还很新。生产中运行的生产级应用程序并不多,尽管这正在快速增长。
有点难学,尤其是所有权模型需要一些时间来适应。
编写 Rust 程序比 Go 等其他语言需要更长的时间,这是因为您需要遵循编译器设置的严格规则。
没有像 Go 那样对并发、异步编程和绿色线程的原生支持。这是设计使然,Rust 对操作系统线程有基本支持,但对于现实世界的异步编程,您需要使用库。futures-rs库包括零成本异步编程的基础。它包括关键特征定义,如,Stream
和实用程序,以及各种期货组合器方法,这些方法支持表达性异步控制流。还有许多可用于并发编程的库和引擎,其中Tokio是最著名和最强大的。join!
select!
CPU 密集型应用程序,例如游戏、操作系统等。
嵌入式系统
应用程序运行时。例如,Node.js 的创建者创建了Deno作为新一代 JavaScript 运行时,这是用 Rust 编写的。
微服务:API,例如REST端点。Rust 拥有一些最快的 Web 框架,例如Actix。
WebAssembly在浏览器中执行高效的代码。它还可用于在Istio等服务网格中编写高效过滤器。
Web开发
加密货币。
由于它的复杂性,我不会使用 Rust 来创建 CLI 和简单的脚本,但这是可能的。
简而言之,这两种新语言非常棒,比解释型或基于 JVM 的语言性能更好,并且使用的资源更少。
但是,每种语言都是为了不同的目的而创建的。
Go的目标是简单和易于使用。它是一种通用语言 。这对于微服务和 DevOps 工具等小型项目非常有用。它还提供了一个非常简单 的语言内置并发模型,让您编写高性能代码是一种非常简单的方法。这使得 Go 成为一种非常强大的语言,也是其受欢迎的关键。您可以在几个小时内开发生产级微服务。Go 可以应用于从 CLI 到 Web 应用程序的广泛用例。
另一方面,Rust是一种专注于性能、低资源使用和低级细节的系统编程语言。虽然 Go 只是借用了一些 C 语法来创建一种通用语言,但 Rust 旨在通过创建一种更简单、更新的编程语言来完全取代 C++。此外,Rust零成本抽象特性和惊人的构建系统允许开发人员创建易于使用但仍然高性能的库,用于通用任务,例如 REST API、流处理等等,从而使 Rust 可以与 Go 竞争。
虽然 Go 主要用于简单的微服务,但 Rust 可用于构建具有数百万行代码的复杂软件。此外,Rust 可用于嵌入式设备、边缘或 WebAssembly;Go 支持有限的环境。
一般来说,Rust 会胜过 Go,但不会好很多,并且会根据用例而有所不同,这是因为垃圾收集器。根据GC运行的频率,结果可能会发生变化。这是 Go 的一个缺点:可预测性。尽管性能差异可能不是很大,但 Rust 的性能是可以预测的。
你可以在这里找到一些初步的比较。如您所见,在 Go 中,很容易犯严重影响性能的错误。换句话说,如果你不密切关注和理解 Go 的工作原理,你的代码将不会有很好的性能并且可能存在运行时缺陷,而在 Rust 中,编译器会引导你并强迫你编写高性能和安全的代码。
在并发方面,两种语言都一样好。Rust 仍然具有更高的性能,但它没有语言内置的并发性,您需要使用诸如Tokio之类的库,而 Go 具有令人惊叹的 Go 例程和运行良好的通道。在我看来,如果你的瓶颈是由阻塞操作引起的,你需要并发和并行而不是 CPU 密集型任务,那么在性能方面不会有太大差异,但 Go 会更容易使用。
如果您是初级开发人员和/或您没有 Java 经验但有 Python 或 C++ 经验,请学习 GO。
如果您负担不起花费数年时间来掌握一门新语言,请学习 GO。
如果您接受 DevOps 文化,请学习 GO。
如果您使用的是 Google Cloud,请学习 GO。
如果您希望获得许多垂直领域的工作机会,请学习 GO。
使用 GO 编写脚本和命令行工具、POC 或快速 API。
如果您想进入加密货币,请学习 Rust。
如果您是高级开发人员和/或 C 开发人员,请学习 Rust。
如果您正在寻找高薪工作但不是很多,请学习 Rust。
如果您想在嵌入式系统或WebAssembly和其他现代工具上工作,请学习 Rust。
如果你想用超快的代码给你的老板留下深刻印象,请学习 Rust。
如果您想使用ADT和高级类型构建复杂的应用程序,请学习 Rust。
如果您想在云、初创企业和酷项目中工作,请学习 Rust 或 GO。
总之,GO好玩又酷,简单易学。在 3 个月内,您可以编写适合实际使用的生产就绪应用程序。Rust复杂且具有挑战性,但也很有价值,它的报酬很高,而且声望更高。这两种语言都在流行,如果您学习它们,您将在云或 Kubernetes 中从事有趣的项目。但是Go仍然更受欢迎。
使用 GO 可以访问许多库和 API,或者将您的程序作为无服务器函数运行。Rust 还有些不成熟。
将 GO 用于自定义脚本、小型作业和 CLI。
使用 GO 进行简单的并发和事件处理。
如果您在云中运行,尤其是在 Google Cloud 中运行,请使用 GO。
将 GO 用于小型项目。
如果您的团队已经了解 C 并且您想编写更安全的代码,请使用 Rust。
将 Rust 用于高并发复杂分布式系统,这些系统利用每一点硬件资源并提供可预测的性能。
使用 Rust 重写应用程序中需要高性能的部分,您可以将其余部分留在另一种语言中。
使用 Rust 远离 C,它们是兼容的。
如果您在一家生产错误非常昂贵的公司(例如医疗保健、航空等)工作,请使用 Rust。
如果您的问题可以通过现有的成熟库(如Tokio、Rocket、Actix等)解决,请使用 Rust。您将获得非常好的性能,而无需付出太多努力。
使用 Rust 生成最小的二进制文件以部署在边缘或嵌入式系统上。
将 Rust 用于大型或 monorepo 项目
模块化是关键的大型代码库的用户 Rust
总之,两种语言都编译为消耗很少资源的二进制文件,Rust 速度更快,占用空间更少,但除非您的团队已经知道 C,否则更难学习。
将 GO 用于无服务器计算和 FaaS 。
如果您在 Google Cloud 中运行,请使用 GO,因为大多数 GCP 服务都基于 GO API。
将 Rust 用于关键的并发应用程序、单体或实时系统。
使用 Rust 来吸引高技能的开发人员。
将 Rust 用于大型代码库和复杂项目。
使用 Rust 构建更环保的项目。
如果您正在寻找添加一种新语言并且您不能花费太多时间,那么 GO 比 Rust 更容易采用。
将 any 用于微服务或 Kubernetes。
简而言之,Rust运行起来更便宜,性能更好,而且 Rust 程序员也非常优秀,如果你使用 Rust,你会吸引人才。问题是 Rust 开发人员并不多,而且很难找到他们。另一方面,GO 更受欢迎,并且不难找到开发人员。这两种语言都很流行,并且使用很少的资源就可以很好地执行。C 甚至 Python 团队会发现迁移到 Rust 比了解其他语言的团队更容易。
Rust是我最喜欢的新语言,它新颖、令人耳目一新、高性能、丰富且可扩展。习惯它需要一些时间,您可能会由于所有权模型而对编译器感到沮丧,但是一旦您习惯了它并理解了规则,它就会变得更容易。
另一方面,GO 更易于使用且更受欢迎。许多 SDK 都有 GO 客户端,但 Rust 客户端较少,因此在开始新项目之前检查一下。例如,有Redis、ElasticSearch、S3等的Rust客户端,但许多其他客户端缺失或太不成熟。
我会建议任何人学习这两种语言,因为它们的受欢迎程度正在增长。可能GO有更好的投资回报;它更容易学习,并且有更多的职位空缺。Rust 仍然很新,我们需要一段时间才能将 Rust 视为大多数工作机会的要求。但是,我会鼓励大家学习 Rust,它会让你成为一个更好的程序员。一旦您对 Rust 感到满意,请尝试确定您的应用程序中将从中受益的组件,并在 Rust 中重新实现它们以提高性能。
一般来说,截至 2022 年,GO是启动新项目的首选语言和更安全的选择,特别是在开发云原生应用程序时。但是,如果您在科技公司工作,那么您应该考虑使用Rust ,这些公司正在扩展并且性能非常重要。Rust的其他用例包括嵌入式系统、高性能应用程序、WebAssembly、加密货币、并发应用程序和任何需要控制底层硬件的复杂应用程序。
但就我个人而言,Rust最好的一点是它的低能耗,Java 几乎翻了一番,而Go 使用了近 3 倍的能耗!. 随着地球上人口的增长和气候变化成为一个问题,我们应该致力于提高能源效率并减少我们的碳足迹。软件无处不在,运行它所需的能量对地球产生了毁灭性的影响;减少能源消耗将对我们的星球产生巨大影响(以及您的云账单!),这非常重要。作为开发人员,我们应该意识到这一点,并尝试学习更节能的语言为创造一个更可持续的地球做出贡献。