5 Better ways to code in Rust

本篇是对 知名Rust视频博主Let's Get Rusty5 Better ways to code in Rust这一视频的翻译与整理, 过程中为符合中文惯用表达有适当删改, 版权归原作者所有.


大家好,在此我将向你展示5种改善Rust编码体验的方法。无论你是完全的初学者还是有经验的Rust开发者,这些技巧对你都很有价值。在视频结束时,我还会分享第六个颇具争议的额外技巧,所以请务必坚持到最后。

好,让我们开始吧。


完美的IDE设置


假设你已经安装了Rust,接下来你要做的是确保正确设置你的IDE。VS Code是我的首选,因为它易于使用,适用于所有主要操作系统,而且高度可配置。要为Rust开发配置VS Code,有三个必备扩展和一些可选但非常强大的扩展,我强烈推荐。

以下是三个必备扩展:

  1. Rust Analyzer: Rust的官方语言服务器,提供代码补全、跳转到定义、内联提示等功能。
  2. CodeLLDB: 这个扩展允许你调试Rust代码。
  3. Better TOML: 为TOML文件提供语法高亮。

有了这三个扩展,就可以开始Rust开发了。此外,还有一些非常强大的可选扩展,也值得安装:

  1. Error Lens: 改善错误和警告的高亮显示。如你所见,它会使错误更突出,并内联显示错误信息。
  2. Todo Tree: 帮助你快速找到代码中的待办事项。Todo Tree的一个很酷的特点是,它使用正则表达式匹配待办事项,你可以更改这个正则表达式。在这个例子中,我更改了正则表达式,使它也高亮显示todo!宏。
  1. crates: 允许你在Cargo.toml文件中轻松检查依赖项是否过时。如果依赖项过时,你会看到一个红色的X,后面跟着该依赖项的最新版本。

自动linting和formating / 实现实时重载 / 设置持续集成


接下来,让我们讨论如何设置你的Rust项目。具体来说,我将介绍如何配置自动代码检查和格式化, 实时重载,以及设置持续集成

自动linting和formating

当你安装Rust工具链时,它附带了两个非常有用的工具:clippy和rustfmt。clippy是一个可配置的代码检查工具,可以捕捉常见错误并改进你的Rust代码。rustfmt是一个可配置的工具,用于按照样式指南格式化Rust代码。你可以在终端中手动运行这些工具,但我喜欢将它们配置为自动运行。让我们看看如何在VS Code中做到这一点。

要配置clippy自动运行,在VS Code中打开设置,在搜索栏中输入”rust-analyzer check”,然后向下滚动直到看到check命令,将”check”改为”clippy”。现在,如果我们打开main.rs,你可以看到我们得到了一个警告,因为我们使用了clippy不允许的变量名。

要配置rustfmt自动运行,我们回到设置并切换到JSON文件配置。然后你只需要这两个配置:确保默认格式化程序是Rust Analyzer,并且保存时格式化设置为true。然后,如果我们回到main.rs并更改代码格式,它会在我们保存文件时被修复。


借助cargo-watch实现实时重载


接下来,让我们讨论如何使用cargo-watch实现实时重载。cargo-watch是一个Cargo插件,它监视项目源文件的变化,并在发生变化时运行Cargo命令。

要安装cargo-watch,运行cargo add cargo-watch

然后你可以运行cargo-watch。这是我喜欢运行的特定命令:

1
cargo watch -q -c -w src -x 'run -q'
  • -q表示安静模式,它会抑制cargo-watch的输出。

  • -c会清除屏幕。

  • -w允许我们指定要监视的文件和文件夹,在这个例子中只监视src目录。

  • -x允许我们指定要执行的Cargo命令,在这个例子中我们执行cargo run并使用-q选项,这将阻止Cargo日志消息被打印。

如果我们执行这个命令,程序将被运行,然后如果我们更改代码,它将被重新编译。


使用GitHub Actions设置持续集成


最后,让我们讨论如何使用GitHub Actions设置持续集成。

要为我们的项目设置持续集成,我们只需要创建一个.github文件夹,其中包含一个workflows文件夹,后者包含了定义我们工作流程的YAML文件。

这里有一个名为”Rust CI”的简单工作流程示例。它在每次代码变更被推送到main分支时,或者每次有针对main分支的pull request时运行。

这个工作流程有一个作业,包含几个步骤:

  1. 首先checkout我们的代码
  2. 然后安装cargo-audit,这将允许我们审计代码库中的漏洞
  3. 接着构建并测试代码
  4. 然后运行cargo clippy,如果出现任何警告则构建失败
  5. 最后运行cargo audit,如果我们的项目依赖项包含任何已知漏洞,构建将失败

有了自动代码检查和格式化、实时重载和持续集成,我们的项目现在已经正确设置,可以开始编码了。


Work->Right->Fast


下一个技巧是如何写Rust有关的方法论。

过度工程是软件开发中的一个常见问题,当你编写的代码比需要的更复杂或更精细时就会发生,这是你在编写Rust时绝对要避免的。

相反,你应该遵循”先使其工作,然后使其正确,最后使其快速”的原则。

首先,编写简单解决问题或完成目标的代码。不管它是否是最地道或最高性能的代码。然后,一旦你的代码工作了,你可以使它更加地道,最后使它更高性能。

让我们看一个例子:

这里我们有一个名为calculate_sum的函数,它接收一个整数数组并返回总和。代码可以工作,但它不是最地道的Rust代码。例如,在calculate_sum函数内,我们使用了for循环而不是迭代器适配器方法,在main函数内,我们对calculate_sum返回的Result类型使用了unwrap,而不是处理错误情况。

现在代码可以工作了,我们可以通过修复这些问题使它更加地道。在calculate_sum内,我们现在使用sum方法而不是for循环,在main函数内,我们对calculate_sum返回的Result类型进行匹配。代码现在更加地道了。

接下来,我们可以考虑性能。为了”挤出”更多性能,我们将使用rayon crate引入并行性。所需要做的就是包含rayon的前导模块,然后在calculate_sum内调用par_iter而不是iter。par_iter代表并行迭代器。rayon将完成如何并行化我们程序的艰难工作。这就是为什么rayon是一个有用且非常流行的Rust crate。


Master key crates


说到Rust crates,下一个技巧是让自己熟悉一些最流行的第三方crates。这一点尤其重要,因为Rust以标准库小而闻名,所以当你编写任何有意义的项目时,很快就会开始使用第三方依赖。

你应该知道的关键crates包括:

  • serde和serde_json: 用于序列化和反序列化你的数据类型
  • thiserror和anyhow: 都用于错误处理
  • tokio: 最流行的Rust异步运行时

还有很多其他重要的crates,在这个视频中没有时间一一介绍,但如果你想要一个精选的Rust crates列表, blessed.rs是一个很好的资源。


Rust特定的设计模式


现在你知道Rust编码的方法论, 以及应该知道一些常用第三方crates,下一个技巧是学习Rust特定的设计模式。例如,扩展trait模式,它允许你在定义类型的crate之外为类型添加方法。当你想扩展标准库中类型的功能时,扩展traits特别常见。

让我们看一个例子:

在一个crate内,假设我们定义了一个名为Palindrome的公共trait,它有一个返回布尔值的is_palindrome函数。然后我们为标准库中的String类型实现Palindrome trait。然后我们可以在另一个crate中导入这个trait,所有的String类型都将可以访问is_palindrome方法。如你所见,这个模式允许我们轻松扩展标准库中类型的功能。

你应该了解的其他一些设计模式包括:类型状态模式、内部可变性、RAII和建造者模式。如果你希望我制作一个视频详细介绍这些特定模式,请在评论区让我知道。



利用AI


现在让我们来到有争议的额外技巧。但在此之前,请确保通过访问letsgetrusty.com/cheatsheet获取你的免费Rust cheatsheet。

第六个额外技巧是利用AI。现在围绕AI有很多兴奋和恐慌,但无论你怎么想,它都已经来了,所以不妨熟悉它并利用它。就我个人而言,我认为AI是一个令人惊叹的工具,可以让你的工作效率大大提高。

例如,像GitHub Copilot这样的工具可以帮助你编写更地道的Rust代码,或帮助你快速实现重复或通用的代码。ChatGPT也是一个非常有用的工具,事实上,它编写了本视频前面提到的GitHub Actions工作流文件。所以,再次强调,确保你了解这些工具并利用它们。



番外: 作用不大,卖课的…

https://www.youtube.com/watch?v=ODk38qJ1A3U

大家好,我是来自travis.media的Travis。当人们第一次决定学习Rust,或者在没有太多经验的情况下尝试使用Rust时,他们真的很难理解Rust标准库。表面上看,这里有太多的信息,而且大部分感觉就像教科书一样。我的意思是,我只是想弄清楚如何四舍五入一个浮点数,但理解标准库对Rust开发来说是至关重要的。

在任何有标准库的语言中,另一个例子是Go,标准库就像一把瑞士军刀,可以用来完成你需要用语言做的大部分事情。与其从头开始编写所有内容,你有一个经过良好测试、内存和性能优化、经过实战检验的代码库,由Rust专家为你预先编写好,供你实现。可以说,要利用这些神奇的工具,你需要知道如何使用它,并且需要非常熟悉它。

所以在这个视频中,我想:

  1. 告诉你为什么你无法理解这个库
  2. 给你一个标准库的大纲,一个框架,以及一些让它成为你的得力助手或文档的技巧
  3. 一个总是让它触手可及的小技巧

所以请看完这个视频,如果它对你来说还不够清楚,那么你至少会有必要的工具来使它变得清楚。让我们开始吧。

第一点,我知道这很明显,但在我开始解释结构和如何阅读标准库之前,我必须说:如果你还没有学完Rust书,那么你会对这个库感到困难。也许如果你来自C或其他类似的低级语言,它会对你更有意义,但如果你来自JavaScript、Python、Ruby或类似的语言,它会看起来像一种外语。这里有结构体、特征、实现,还有很多关于栈和堆的讨论,所有这些都会使理解变得更加困难。

因此,对于任何难以理解Rust标准库的人来说,这里是第一步:一章一章地学完整本Rust书。学习概念,研究例子,最重要的是,使用那些链接,这些链接会带你到标准库,进一步阅读你正在学习的概念。

这里有一个例子:在第2章中,我们学习了这个readline方法,它将用户输入的内容放入我们传递给它的字符串中,但它也返回一个结果值。什么是结果值?它在这里告诉你结果是一个枚举,巴拉巴拉巴拉,但你不应该只是这样做。只读这个然后继续前进,说我以后再学,这很诱人,但这里是你应该做的:

那个result单词是一个链接,打开链接,它会带你到标准库,告诉你这是一个枚举,它有两个变体。但你还应该做的是学习这在标准库中的位置,以便你以后需要时再次找到它。所以这里我看到它在标准库和result模块中。让我们回到主页,向下滚动找到模块,然后在这里我们会找到result。点击result,这就是那个页面,但这不是他们链接到的完全相同的页面。要找到他们链接到的内容,你需要向下滚动,越过所有的例子,进入str和enum。在这里的enum中,这里是result enum,点击它,你就到了这个页面。所以你不仅学习了什么是result,还学习了它在标准库中的位置。

这里还有另一个例子:我们有一个String。String是标准库提供的一种类型,它是一个可增长的UTF编码的文本。与其只是读这个然后继续,为什么不点击String链接,看看它在标准库中的位置呢?在这里我们可以阅读关于String的内容,我们可以看到例子,但关键是要找出它在标准库中的位置。这里告诉我们它在标准库、string模块和string结构体中。让我们看看我们能否找到它。让我们回到主页,向下滚动到模块,找到string。这里是string,但这不是他们链接到的同一个页面。所以让我们继续向下滚动,在结构体下我们会找到string结构体。然后从那里我们可以向下滚动,找到实现,比如他们给我们的new函数的例子。

所以重点不仅是在你通过这本书学习时学习概念,还要找出这些东西在标准库中的位置。所以你前期能做的最好的事就是从头到尾地完成Rust书的工作。它是完全免费的,我会在下面放一个链接。如果你想和社区中的其他人一起学习,一定要查看Impostor Devs社区,我们每周一起学习这本书的一章。我会在下面放一个链接。但如果你在学习这本书时参考标准库,我保证当你学完后,它会比现在有意义100倍。

现在在我们进入第二点之前,也就是这个标准库的大纲或框架,让我快速提一下今天的赞助商Brilliant,它可以帮助你用计算机科学原理补充你的Rust学习。

brilliant.org是一个很好的方式,可以交互式地学习数学、逻辑和计算机科学。Brilliant很有趣,很实用,有数千个从基础到高级主题的课程,从计算机科学和编程算法、Python、AI、逻辑和其他工具,帮助你提升技能或保持技能敏锐。而且它是为像我和你这样忙碌的人设计的。就像我说的,你可以在短短15分钟内掌握大概念。也许你在掌握数据结构如链表或核算操作方面有困难,Brilliant会以一种引人入胜的交互方式帮助你可视化和内化这些概念。

今天我花了10分钟继续学习算法导论课程,我学习了算法如何操作和存储数字,数组如何工作,以及如何搜索它们。就像我说的,Brilliant可以帮助你巩固那些可以应用于不同编程语言的编码技能和概念。你今天就可以免费开始30天的学习,使用下面的链接,前200名使用该链接注册的人将获得年度订阅20%的折扣。链接是brilliant.org/travismedia。现在回到视频。

好的,接下来让我给你一个快速的大纲,一个关于如何阅读和导航标准库的分解。让我们去主页,我们会在这里看到一个基本定义:Rust标准库是可移植Rust软件的基础,是更广泛的Rust生态系统的一组最小的和经过战斗测试的共享抽象。很好,读一读如何阅读文档。但下一节是我想触及的。

标准库有四个主要部分,实际上是五个:

  1. 模块。首先,Rust标准库被分成了许多专注的模块,所有这些都在页面下方列出。这些模块是所有Rust的基石,它们有威严的名字,如std::slice和std::cmp模块。文档通常包括模块的概述以及示例,是开始熟悉库的明智之处。需要示例吗?从模块开始。让我们向下滚动,我们会找到一个叫做模块的部分,在这里我们可以选择一个,比如io模块,你会找到很多例子,比如读和写。如果你继续向下滚动,你会找到标准输入和输出的例子。这实际上就是你在Rust书的第2章中使用的确切代码。所以这些是模块,是标准库的基石,也是你会找到大多数你正在寻找的例子的地方。

  2. 原始类型。其次,原始类型上的隐式方法在这里有文档。如果你向下滚动,就在模块上面,你会看到原始部分。这里是Rust的原始类型。所以你有数组、布尔、字符、浮点数、整数、字符串、元组,所有的原始类型都在这里。如果你想知道你可以在它们上面调用什么方法,那么就选一个,比如让我们选布尔。所以这里是定义,这里是一些例子,如果你向下滚动,你会到达实现。

  3. Rust前奏。第三,标准库定义了Rust前奏。让我们点击那个。一小部分项目,主要是特征,被导入到每个crate的每个模块中。前奏中的特征是普遍存在的,使前奏文档成为学习库的一个好的入口点。所以前奏中的项目被拉入每个crate,你不必使用use语句从标准库中引入它,它们被带入每个crate,我们点击了那个链接,你可以在这里阅读关于前奏的内容。

  4. 宏。最后,标准库导出了许多标准宏,并在这个页面上列出了它们。向下滚动,你会找到宏的部分。你可能最熟悉的一个是println!宏。点击那个,我们会得到关于它的信息。

  5. 关键字。我想添加的第五项是关键字。就在那下面是关键字。这里你会找到async,如果你在做循环,你会找到break,你会找到continue。这里你会找到match关键字,loop关键字等等。

这就是标准库的五个主要项目:模块、原始类型、Rust前奏、宏和关键字。它们都在这个页面上。

现在这里有一个小作业给你。回到我们之前在这个下一节说”A tour of the Rust standard library”的地方。去阅读”A tour of the Rust standard library”这一节。这里有容器和集合、平台抽象和IO,以及在main之前和之后使用。阅读这些部分,在接下来的几周内,点击这些链接,熟悉这些术语,它们是什么,在库中哪里可以找到它们。

所以这里你读到str,一个UTF-8字符串切片是一个原始类型,很好,标准库为它定义了许多方法。Rust的str或字符串通常作为不可变引用访问,看这里的引用符号&。使用拥有所有权的String来构建和修改字符串。所以这里有一个区别,有String和str。有什么区别?我们在标准库中查看一下。

所以这是你的作业,阅读”A tour of the Rust standard library”这一节,在接下来的几周内,查看这些链接,并知道在库中哪里可以找到它们。

现在最后我想让你做的是在VS Code中查看rust-analyzer扩展。这个扩展不仅给你所有类型的提示,如类型提示和参数提示,而且还直接链接到你本地机器上的文档。所以这里你看到String,这不是我输入的,这告诉我这是一个String。你会在这里看到Result,我没有输入这个,但它告诉我这个readline方法返回一个Result。但有趣的是,我可以悬停在像String这样的东西上,我会得到这个文档。所以我找出什么是String,并得到如何使用它的例子。

同样,如果我悬停在new函数上,我会得到一个定义,我会得到一些例子,然后我会得到这个”go to String”。现在如果我点击这个,它带我到这里。那么这是什么呢?这是实际的Rust标准库文档。如果我滚动到顶部,你会看到这里有一个UTF-8编码的可增长字符串,这里有一些例子,所有那些。如果我回到String的文档,你会看到完全相同的东西。它实际上就是文档。如果我点击Source,我应该看到完全相同的格式化的东西,有所有这些注释段落。

所以下载那个扩展,它会给你文档,字面上只需点击一下就可以了。如果你厌倦了看到所有这些帮助,比如String和Result类型,以及什么被返回等等,那么这个扩展给你选项来禁用这些。如果你去rust-analyzer文档,你会找到像这样的设置,你可以把它们设置为false,所有那些都会消失,你仍然可以使用文档,悬停在String上,悬停在io::stdin上,我的文档仍然在那里。

我希望这对你有帮助。我希望这能帮助你深入研究标准库,这对成为一个真正优秀的Rust开发者来说是关键。你怎么看?你对标准库有困难吗?它对你来说一直很令人困惑吗?让我们在下面讨论一下。如果你觉得这个视频有帮助,请给它一个赞,考虑订阅频道如果你还没有,我会在下一个视频中见到你。谢谢观看。


20250217

https://github.com/cordx56/rustowl

给 Rust 开发者推荐一款开源的 VS Code 插件:RustOwl。

通过该插件,可以在 Rust 代码文件上可视化变量的所有权移动和生命周期,并通过不同颜色的下划线标识不同类型。

GitHub:github.com/cordx56/rustowl

对于我们开发者来说,用来调试、分析和阅读代码非常有用,编程效率定有所提升。