您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Rust

不要按照 Java 的方式编写 Rust

时间:2023-10-13 12:50:14  来源:CSDN  作者:

【CSDN 编者按】停止按照 JAVA 的方式编写 Rust,这是我发现编写 Rust 代码的乐趣。

原文链接:https://jgayfer.com/dont-write-rust-like-java

作者 | James Gayfer译者| 弯月

责编 | 夏萌

出品 | CSDN(ID:CSDNnews)

多年来,我一直对 Rust 很感兴趣。类型安全、内存安全并且强调正确性。谁能不爱?

我在开发 Apollo(一款 Python/ target=_blank class=infotextkey>Python 应用)时遇到过很多错误,假如我使用的是 Rust,那么大多数错误都可以被 Rust 编译器捕获(虽然达不到百分百,但比例应该会很高)。一般来说,编译器可以捕获许多问题,而在使用动态语言(如 Python 或 Ruby)时,这些问题有可能进入生产环境,尽管并非所有编译器都能做到这一点。类型安全非常棒,但 Rust 十分注重正确性,这才是最吸引我的地方。

我在工作中编写了大量 Java 代码。虽然 Java 不是我最喜欢的语言,但它的编译时检查很强大。在进行重大重构时,Java 没有使用 Python 或Ruby 那么可怕。有了这样的编译器,遇到不正确或遗漏的导入语句,程序在运行时就会停止。虽然我们通常会通过测试来发现这些问题,但是将这些检查融入到语言中还是很有必要的。

然而 Java 编译器并不完美。它无法防止许多种错误,其中最令人头疼的就是空引用。在Java 中几乎所有东西都可以为 null,相关的错误直到运行时你才能发现。与之相反,Rust 拥有适当的结构来引导你处理未知值。当然,你可以选择忽略此类提示,但编译器会强制你做出深思熟虑的决定。

那么,Rust 是否比 Java 更好呢?Rust确实有许多让我很喜欢的地方。Rust 的承诺对我来说非常有吸引力。但我的 Rust 之旅并不全是阳光和彩虹。尽管 Rust 与 Java 有相似之处,但二者并不一样。直到停止按照 Java 的方式编写 Rust,我才发现了编写 Rust 代码的乐趣。

一切必须是接口

对于 Java 开发人员(我就是这样的开发人员)来说,一切都是接口,虽然这个说法不完全准确,但也有一定的道理。Java 中的接口使用起来很有趣。应用程序由小的工作单元组成,每个工作单元都不了解另一个工作单元的内部工作原理。建立这样的依赖关系树需要在前提付出不少努力,但一旦完成,就能拥有一支独立服务的大军供你使用。

然而,Rust 中没有接口,有的是特征(trAIt)。这些特征在很多方面与 Java 中的接口很相似。然而,我们不应该将 Rust 中的一切都写成特征。记住,Rust 的内存安全是一个很强大的功能。而代价是无法轻松“注入”实现特征的代码。

不要按照 Java 的方式编写 Rust

上面的代码无法编译,因为编译时无法确定 Named 的大小。为了解决这个问题,我们可以将这个特征放入Box ,这样我们就可以指向堆上动态分配的内存(称为 trait 对象)。Box 本身的大小已知,因此程序就可以编译了。

不要按照 Java 的方式编写 Rust

Box不太方便使用,因此我不太喜欢这种模式。我会尽可能避开它们。我们可以使用泛型来指定 特征类型。

不要按照 Java 的方式编写 Rust

这两种方式有何不同?初看之下结果是一样的。实际上二者的差异在于动态调度与静态调度。对于特征对象,具体的类型是在运行时解析的,而泛型的具体类型是在编译时解析的。

实际上,这意味着只要我们可以在编译时推断所有类型,就可以不使用泛型。如果直到运行时才能推断类型,则必须使用 Box。

所有权

所有权的问题依然存在。如果上述 Named 特征是应用程序中其他服务的必需依赖项,该怎么办?我们是否需要创建一个主Named ,然后将 &Named 传递给每个依赖项,这样就会引入生命周期?

还是说我们应该使用 Arc,这样依赖服务就可以写为 Arc<Box<dyn Named>>,从而允许并发访问所拥有的资源?

两种方法我都尝试过了,虽然可行,但都不太理想,尤其是当应用程序中的每项服务都受到影响时。

纯函数

将 Rust 当成纯粹的面向对象语言并不合适。虽然我仍然像上面的例子一样编写“服务对象”,但只在必要时使用它们,实际上我更推荐纯函数。

我们来考虑一个处理结账事件的函数,该函数会更新系统中的客户 ID。

不要按照 Java 的方式编写 Rust

虽然我们可以将这段处理编写为一个服务,其中的 UserRepo 是一个注入值,但上面我们已经探讨过了,这样做会带来一定的复杂性。此外,我们仍然可以轻松注入 UserRepo 的不同实现,例如提供不会访问生产数据库的实现,因此也没有理由将其编写为服务。缺点在于,我们的函数签名可能会有点“繁忙”,不过这种程度的“痛苦”根本不算什么。

拥抱真正的 Rust

以前我深陷“Rust 语言很难”的误区不能自拔。一个重要原因是我坚持按照其他语言的方式编写 Rust 代码。虽然汲取以往的经验很重要,但拥抱 Rust 本身的惯用写法对于掌握这门语言也很重要。只有转变心态才能真正掌握 Rust。按照不适合的方式编写 Rust 会让我们陷入苦苦的挣扎,我们应该拥抱它本来的样子。



Tags:Rust   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
在Rust中使用Serde的详细指南
在处理HTTP请求时,我们总是需要在一种数据结构(可以是enum、struct等)和一种可以存储或传输并稍后重建的格式(例如JSON)之间来回转换。Serde是一个库(crate),用于高效、通用地...【详细内容】
2024-03-26  Search: Rust  点击:(15)  评论:(0)  加入收藏
Rust 写脚手架,Clap你应该知道的二三事
有感而发最近,在和前端小伙伴聊天发现,在2024年,她们都有打算入局Rust学习的行列。毕竟前端现在太卷了,框架算是走到「穷途末路」了,无非就是在原有基础上修修补补。所有他们想在...【详细内容】
2024-03-11  Search: Rust  点击:(20)  评论:(0)  加入收藏
前端开始“锈化”?Vue团队开源JS打包工具:基于Rust、速度极快、尤雨溪主导
Vue 团队已正式开源Rolldown &mdash;&mdash; 基于 Rust 的 JavaScrip 打包工具。Rolldown 是使用 Rust 开发的 Rollup 替代品,它提供与 Rollup 兼容的应用程序接口和插件接口...【详细内容】
2024-03-09  Search: Rust  点击:(11)  评论:(0)  加入收藏
Rust中的数据可视化指南
可视化是数据分析和解释的一个关键方面。虽然Rust主要以其性能和安全特性而闻名,但它也为数据可视化提供了强大的工具。在这个全面的指南中,我们将深入研究Rust中的数据可视化...【详细内容】
2024-03-07  Search: Rust  点击:(29)  评论:(0)  加入收藏
如何在Rust中操作JSON,你学会了吗?
sonic-rs ​还具有一些额外的方法来进行惰性评估和提高速度。例如,如果我们想要一个 JSON​ 字符串文字,我们可以在反序列化时使用 LazyValue​ 类型将其转换为一个仍然带有斜...【详细内容】
2024-02-27  Search: Rust  点击:(47)  评论:(0)  加入收藏
记一次Rust内存泄漏排查之旅
在某次持续压测过程中,我们发现 GreptimeDB 的 Frontend 节点内存即使在请求量平稳的阶段也在持续上涨,直至被 OOM kill。我们判断 Frontend 应该是有内存泄漏了,于是开启了排...【详细内容】
2024-02-27  Search: Rust  点击:(12)  评论:(0)  加入收藏
Rust 最受欢迎的这些库
今天分享主题是,关于一些值得注意的 Rust 库,这些库可以根据它们的功能和在编码中的受欢迎程度进行选择。什么是 Rust 库?在 Rust 中,常被称为 “crate” 的库,是一个打包的单元...【详细内容】
2024-02-19  Search: Rust  点击:(50)  评论:(0)  加入收藏
异步Rust:构建实时消息代理服务器
在本文中,我们将深入研究使用Rust构建实时消息代理服务器,展示其强大的并发特性。我们将使用Warp作为web服务器,并使用Tokio来管理异步任务。此外,我们将创建一个WebSocket客户...【详细内容】
2024-02-01  Search: Rust  点击:(57)  评论:(0)  加入收藏
在 Rust 编程中使用泛型
本文的内容将涉及泛型定义函数、结构体、枚举和方法, 还将讨论泛型如何影响代码性能。1.摘要Rust中的泛型可以让我们为像函数签名或结构体这样的项创建定义, 这样它们就可以...【详细内容】
2024-01-09  Search: Rust  点击:(89)  评论:(0)  加入收藏
什么是Rust语言 ,特点是什么,跟其它语言对比有什么优势
什么是RustRust是一种系统编程语言,旨在提供高性能和安全性。它是由Mozilla和其开发社区创建的开源语言,设计目标是在C++的应用场景中提供一种现代、可靠和高效的选择。Rust的...【详细内容】
2024-01-09  Search: Rust  点击:(204)  评论:(0)  加入收藏
▌简易百科推荐
在Rust中使用Serde的详细指南
在处理HTTP请求时,我们总是需要在一种数据结构(可以是enum、struct等)和一种可以存储或传输并稍后重建的格式(例如JSON)之间来回转换。Serde是一个库(crate),用于高效、通用地...【详细内容】
2024-03-26  coding到灯火阑珊  微信公众号  Tags:Rust   点击:(15)  评论:(0)  加入收藏
Rust 写脚手架,Clap你应该知道的二三事
有感而发最近,在和前端小伙伴聊天发现,在2024年,她们都有打算入局Rust学习的行列。毕竟前端现在太卷了,框架算是走到「穷途末路」了,无非就是在原有基础上修修补补。所有他们想在...【详细内容】
2024-03-11  前端柒八九  微信公众号  Tags:Rust   点击:(20)  评论:(0)  加入收藏
Rust中的数据可视化指南
可视化是数据分析和解释的一个关键方面。虽然Rust主要以其性能和安全特性而闻名,但它也为数据可视化提供了强大的工具。在这个全面的指南中,我们将深入研究Rust中的数据可视化...【详细内容】
2024-03-07  coding到灯火阑珊  微信公众号  Tags:Rust   点击:(29)  评论:(0)  加入收藏
如何在Rust中操作JSON,你学会了吗?
sonic-rs ​还具有一些额外的方法来进行惰性评估和提高速度。例如,如果我们想要一个 JSON​ 字符串文字,我们可以在反序列化时使用 LazyValue​ 类型将其转换为一个仍然带有斜...【详细内容】
2024-02-27  前端柒八九  微信公众号  Tags:Rust   点击:(47)  评论:(0)  加入收藏
记一次Rust内存泄漏排查之旅
在某次持续压测过程中,我们发现 GreptimeDB 的 Frontend 节点内存即使在请求量平稳的阶段也在持续上涨,直至被 OOM kill。我们判断 Frontend 应该是有内存泄漏了,于是开启了排...【详细内容】
2024-02-27  OSC开源社区    Tags:Rust   点击:(12)  评论:(0)  加入收藏
Rust 最受欢迎的这些库
今天分享主题是,关于一些值得注意的 Rust 库,这些库可以根据它们的功能和在编码中的受欢迎程度进行选择。什么是 Rust 库?在 Rust 中,常被称为 “crate” 的库,是一个打包的单元...【详细内容】
2024-02-19  码农渔夫  微信公众号  Tags:Rust   点击:(50)  评论:(0)  加入收藏
异步Rust:构建实时消息代理服务器
在本文中,我们将深入研究使用Rust构建实时消息代理服务器,展示其强大的并发特性。我们将使用Warp作为web服务器,并使用Tokio来管理异步任务。此外,我们将创建一个WebSocket客户...【详细内容】
2024-02-01      Tags:Rust   点击:(57)  评论:(0)  加入收藏
在 Rust 编程中使用泛型
本文的内容将涉及泛型定义函数、结构体、枚举和方法, 还将讨论泛型如何影响代码性能。1.摘要Rust中的泛型可以让我们为像函数签名或结构体这样的项创建定义, 这样它们就可以...【详细内容】
2024-01-09  二进制空间安全  微信公众号  Tags:Rust   点击:(89)  评论:(0)  加入收藏
什么是Rust语言 ,特点是什么,跟其它语言对比有什么优势
什么是RustRust是一种系统编程语言,旨在提供高性能和安全性。它是由Mozilla和其开发社区创建的开源语言,设计目标是在C++的应用场景中提供一种现代、可靠和高效的选择。Rust的...【详细内容】
2024-01-09    简易百科  Tags:Rust语言   点击:(204)  评论:(0)  加入收藏
在 Rust 编程中使用多线程
编程语言有一些不同的方法来实现线程,而且很多操作系统提供了创建新线程的 API。Rust 标准库使用 1:1 线程实现,这代表程序的每一个语言级线程使用一个系统线程。1. Rust线程...【详细内容】
2024-01-07  二进制空间安全  微信公众号  Tags:Rust 编程   点击:(77)  评论:(0)  加入收藏
站内最新
站内热门
站内头条