百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

十年 Python 程序员,初次尝试 Rust:“非常优秀!”

itomcoil 2025-01-24 12:16 45 浏览

摘要:Python 和 Rust,都是近几年深受开发者喜爱的编程语言,那么作为一个拥有十年 Python 编程经验的开发者来说,初次尝试 Rust 会有怎样的感受呢?

链接:https://karimjedda.com/carefully-exploring-rust/

声明:本文为 CSDN 翻译,未经允许禁止转载。


作者 | Karim Jedda
译者 | 弯月 责编 | 郑丽媛
出品 | CSDN(ID:CSDNnews)

最近,我找到了一份新工作,公司最常用的编程语言之一是 Rust。

在此之前,我使用 Python 长达十年之久,主要是做数据工程的工作。但如今,我打算尝试一下这种新的(对我来说)编程语言。我经常在不同平台上看到各类夸赞 Rust 的文章,我想看看 Rust 是否真的不负盛名。

Rust 与 Python 有很大的不同,因此我不打算在本文中详细说明 Rust 的独特之处。作为初学者,我只希望尽快上手,希望能以最短的过渡,尽快 Rust 完成工作,同时也希望评估一下我自己的学习能力。

从某种程度上来说,我更感兴趣的是 Rust 整体的使用体验,而不是具体的功能列表。


设置开发环境


设置开发环境非常简单,只需参照 Rust 网站提供的示例,在终端中运行一个命令就可以了。

当你认为一切都已安装并配置妥当,此时如果想验证 Rust 是否已正确安装,只需在空目录中创建一个空项目:

cargo new tutorialcd tutorialcargo run

接下来,在文本编辑器中打开该文件夹。如果你是新手,我推荐 VSCode,因为其中的一些扩展很有帮助,关于如何使用这些扩展的指南也很容易入手。我推荐 rust-analyzer 作为 VSCode 的唯一扩展。


输出与调试

如果想了解程序是如何运行的,首先要做的就是通过命令行来了解程序在干什么,以及完成了什么。

此外,你还可以使用常规调试器。在 M1 上,我推荐在 Visual Studio Code 中使用 LLDB,它不仅工作良好,通常还要比在输出结果中打印日志更为方便。

到这里为止,Rust 与 Python 其实都非常相似,只不过所有命令都是通过 cargo run 运行的,而不是调用特定文件,如 python3 somefile.py。

另外,你也可以先运行 cargo build,然后运行 target/debug/tutorial 中的文件,得到的结果是相同的。接下来,如果将生成的文件复制到另一个位置或另一台类似的机器上,也可以正常工作,且无需安装任何与 Rust 相关的东西。


错误处理


不得不承认,编程中总会遇到一些意外,能够以可预测的方式处理这些意外非常重要。编程中的一大挑战就是很难考虑到程序中所有可能出现的错误,因为只要写代码就可能会出错。

“每个人都知道调试比编写程序要难一倍。所以,如果你在代码编写代码时就用尽了聪明才智,又如何调试呢?”

—— Brian W. Kernighan

在 Python 中,通常我们通过 try/except 方法来抛异常,并完成错误处理。我们运行一段代码,如果出错,则通过条件来捕捉异常,如果所有条件都不匹配,则将其放入一个通用的异常中。异常有各种不同的类别,Python 允许你在包中调用不存在的函数,并在运行时产生异常,但在 Rust 中这样做甚至无法通过编译——Rust 不允许在运行时出现任何奇怪的错误,从而消除了一大类不太容易预测的错误。

下面通过一个例子来说明 Rust 的这种方法,同时我会用 Python 的术语进行解释。

在上面的代码中,我们创建了一个自定义的异常,在 do_something 函数中抛出,而 main 函数会检查该异常。上面的代码跟 try/exept 基本上一样,只不过多了一些样板代码这些样板代码是必须的,但以我现在的水平有点难以理解

你也许会说“肯定有更好的办法”,特别是如果你有很多 Python 经验的话,的确如此,我们将不得不使用包。。


使用外部包


与其他行业相比,编程的最大优势就是可以使用别人构建的东西。如果你计划在程序中进行错误处理,那么有一个很好用的包 thiserror。Rust 的包管理器是 cargo。

Rust 中的包叫做 crate。安装方法为编辑目录下的 Cargo.toml 文件。在本例中,我们在 [dependencies] 后面添加 thiserror = "1.0" 就可以了。

然后可以像下面这样重写之前的代码:

现在代码看起来很正常。与一切从头开始相比,我更喜欢这种做法。

我花了四五年时间才找到用 Python 编程的乐趣,所以我也愿意多花些时间来探索 Rust 的高级功能。Rust 有许多错误处理的方法,而我喜欢更简单的方法。

我有意略过了一些简单的概念,比如“什么是 enum?” “pub 是什么意思?” “那些#标记是什么”等,因为你只需运行一下代码就能明白它们的意思。

一切看起来都还不错。那么,测试方面又如何呢?


编写测试


测试应该从单元测试和集成测试两个级别上着手。实现方法有好几种,虽然你可以把测试代码和 Rust 代码放在同一个文件中(这也是官方指南的推荐),但我还是希望用一个单独的文件夹来组织所有测试代码,这样可以减少阅读代码时的负担,也可以减少编辑文件时占用的屏幕面积。而且说实话,在编写测试和编写代码时,我的心情是不一样的。

方法之一如下:

然后可以用 cargo test 运行测试,结果如下:

还有许多值得展开讲的地方,但为了避免过于复杂,我们点到为止,这算是“帕累托最优”(又称80/20法则)。这让我想起了 pytest,一个能即刻提高舒适度的工具。


读取文件、运行一些代码并写入另一个文件


以上,我们讨论了一些最基本的问题:输出,调试,使用外部包,以及测试。下面,我们来做一些更有效率的事情:我们可以写一个程序来处理本地文件。下面的例子将会读取 CSV 文件,计算一些数值,然后将输出结果。

为了实现该程序,我们需要在 Cargo.toml 中添加以下两行设置:

  • csv="1.1"

  • serde={version="1", features=["derive"]}

你可以猜猜 main() 函数应该怎样写。

当然,这个程序还可以实现更多功能。如果你有一个非常复杂的 CSV 文件,则可以在 Rust 中调用 pandsa(pola.rs)来处理数据。我还需要进一步研究,不过似乎这种处理方法非常强大且高效

我认为,与 Python 相比,Rust的 CSV 处理能力不相上下,除了它能自动反序列化之外。

最后,我们还可以添加一些测试,此处不再赘述。


发送 HTTP 请求


下面,我们来尝试发送基本的 HTTP 请求并处理结果。现在的绝大多数请求都需要处理 JSON。

在 Cargo.toml 中添加如下几行代码:

reqwest = { version = "0.11", features = ["json"] }tokio = { version = "1", features = ["full"]}serde_json = "1"

这样就可以了,现在可以从 API 请求数据了。结合使用上面两个方法,我们可以获取数据,用 pola.rs 进行分析,然后将结果写入 CSV 文件中,同时保证内存安全。还记得 Python 需要循环才能实现这一点吗?在这方面 Rust 做得很好。

我相信,Rust 的生态系统会越来越大,以覆盖更多的用例,以后利用已有的 crate 实现这一切会易如反掌。


使用 SQLite


虽然在这篇文章中提到 SQLite 似乎有些奇怪,但我开发过的程序经常用到 SQLite。我很喜欢 SQLite,因为它是可移植的,非常有效,而且不需要任何维护。

用 Python 操作 SQLite 的问题永远是要不要使用 ORM。请不要误会,SQLAlchemy 非常优秀,但在进行非常小的操作时,用它就像杀鸡用牛刀了。而且 SQLAlchemy 带来的复杂性使它不适合小型嵌入式设备。

反之, Rust 可以在这方面大放异彩,网上有很多如何利用Rust操作 SQLite 的例子,我认为都非常不错。

举个简单的例子,别忘了在 Cargo.toml 中添加下面这行代码:

rusqlite = { version = "0.28.0", features = ["bundled"] }

该例子来自 rusqlite crate。当然,这只是冰山一角。但组合以上几种方法,就可以实现许多很有用的功能了。


总结


综合考虑,Rust 是一个非常优秀的语言,有许多优秀的包,非常感谢发明这门语言并为之努力贡献的开发者们。虽然这篇文章只是对 Rust 做了初步的探索,但我希望抛砖引玉,让初学者产生学习 Rust 的兴趣。

初次使用某种编程语言时,重点在于弄清楚语言本身能实现哪些功能,而不是背诵一篇完整的术语表。你不需要去理解 borrowing、继承或 traits 的具体含义,而应该跟随些入门文章按部就班地做一遍。

从无到有的难度远大于从一到十。

相关推荐

《Queendom》宣布冠军!女团MAMAMOO四人激动落泪

网易娱乐11月1日报道据台湾媒体报道,南韩女团竞争回归的生死斗《Queendom》昨(10/31)晚播出大决赛,并以直播方式进行,6组女团、女歌手皆演唱新歌,并加总前三轮的赛前赛、音源成绩与直播现场投...

正确复制、重写别人的代码,不算抄袭

我最近在一篇文章提到,工程师应该怎样避免使用大量的库、包以及其他依赖关系。我建议的另一种方案是,如果你没有达到重用第三方代码的阈值时,那么你就可以自己编写代码。在本文中,我将讨论一个在重用和从头开始编...

HTML DOM tr 对象_html event对象

tr对象tr对象代表了HTML表格的行。HTML文档中出现一个<tr>标签,就会创建一个tr对象。tr对象集合W3C:W3C标签。集合描述W3Ccells返回...

JS 打造动态表格_js如何动态改变表格内容

后台列表页最常见的需求:点击表头排序+一键全选。本文用原生js代码实现零依赖方案,涵盖DOM查询、排序算法、事件代理三大核心技能。效果速览一、核心思路事件入口:为每个<th>绑...

连肝7个晚上,总结了66条计算机网络的知识点

作者|哪吒来源|程序员小灰(ID:chengxuyuanxiaohui)计算机网络知识是面试常考的内容,在实际工作中经常涉及。最近,我总结了66条计算机网络相关的知识点。1、比较http0....

Vue 中 强制组件重新渲染的正确方法

作者:MichaelThiessen译者:前端小智来源:hackernoon有时候,依赖Vue响应方式来更新数据是不够的,相反,我们需要手动重新渲染组件来更新数据。或者,我们可能只想抛开当前的...

为什么100个前端只有1人能说清?浏览器重排/重绘深度解析

面试现场的"致命拷问""你的项目里做过哪些性能优化?能具体讲讲重排和重绘的区别吗?"作为面试官,我在秋招季连续面试过100多位前端候选人,这句提问几乎成了必考题。但令...

HTML DOM 介绍_dom4j html

HTMLDOM(文档对象模型)是一种基于文档的编程接口,它是HTML和XML文档的编程接口。它可以让开发人员通过JavaScript或其他脚本语言来访问和操作HTML和XML文档...

JavaScript 事件——“事件流和事件处理程序”的注意要点

事件流事件流描述的是从页面中接收事件的顺序。IE的事件流是事件冒泡流,而NetscapeCommunicator的事件流是事件捕获流。事件冒泡即事件开始时由最具体的元素接收,然后逐级向上传播到较为不...

探秘 Web 水印技术_水印制作网页

作者:fransli,腾讯PCG前端开发工程师Web水印技术在信息安全和版权保护等领域有着广泛的应用,对防止信息泄露或知识产品被侵犯有重要意义。水印根据可见性可分为可见水印和不可见水印(盲水印)...

国外顶流网红为流量拍摄性侵女学生?仅被封杀三月,回归仍爆火

曾经的油管之王,顶流网红DavidDobrik复出了。一切似乎都跟他因和成员灌酒性侵女学生被骂到退网之前一样:住在950万美元的豪宅,开着20万美元的阿斯顿马丁,每条视频都有数百万观看...人们仿佛...

JavaScript 内存泄漏排查方法_js内存泄漏及解决方法

一、概述本文主要介绍了如何通过Devtools的Memory内存工具排查JavaScript内存泄漏问题。先介绍了一些相关概念,说明了Memory内存工具的使用方式,然后介绍了堆快照的...

外贸独立站,网站优化的具体内容_外贸独立站,网站优化的具体内容有哪些

Wordpress网站优化,是通过优化代码、数据库、缓存、CSS/JS等内容,提升网站加载速度、交互性和稳定性。网站加载速度,是Google搜索引擎的第一权重,也是SEO优化的前提。1.优化渲染阻塞。...

这8个CSS工具可以提升编程速度_css用什么编译器

下面为大家推荐的这8个CSS工具,有提供函数的,有提供类的,有提取代码的,还有收集CSS的统计数据的……请花费两分钟的时间看完这篇文章,或许你会找到意外的惊喜,并且为你的编程之路打开了一扇新的大门。1...

vue的理解-vue源码 历史 简介 核心特性 和jquery区别 和 react对比

一、从历史说起Web是WorldWideWeb的简称,中文译为万维网我们可以将它规划成如下的几个时代来进行理解石器时代文明时代工业革命时代百花齐放时代石器时代石器时代指的就是我们的静态网页,可以欣...