公司内部的学习会非常活跃!我也参与了Rust学习会,并且一直在研究rustlings。最近,我发现了一个类似于rustlings的新教程网站:Welcome - 100 Exercises To Learn Rust。
rustlings是基于Rust的权威官方文档《The Rust Programming Language》(简称TRPL)制作的,而100-exercises则在特性和异步处理等方面深入探讨,比TRPL更具挑战性,真的很值得一试!
接下来的一段时间,我会挑战"100 Exercises To Learn Rust",并将这个过程记录下来写成文章。那么,让我们开始今天的准备篇吧!
环境搭建
这次我选择在 Ubuntu 24.10 上进行挑战!安装方法可以在官方网站上查看。
https://www.rust-lang.org/zh-CN/tools/install
不过,这其实一点也不难。Rust的安装非常简单,只需一行命令就可以完成,而且不需要管理员权限!
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
info: downloading installer
Welcome to Rust!
~~ 省略 ~~
Current installation options:
default host triple: x86_64-unknown-linux-gnu
default toolchain: stable (default)
profile: default
modify PATH variable: yes
1) Proceed with standard installation (default - just press enter)
2) Customize installation
3) Cancel installation
>
在这里选择1。
1) Proceed with standard installation (default - just press enter)
2) Customize installation
3) Cancel installation
>1
~~ 省略 ~~
stable-x86_64-unknown-linux-gnu installed - rustc 1.78.0 (9b00956e5 2024-04-29)
Rust is installed now. Great!
To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).
To configure your current shell, you need to source
the corresponding env file under $HOME/.cargo.
This is usually done by running one of the following (note the leading DOT):
. "$HOME/.cargo/env" # For sh/bash/zsh/ash/dash/pdksh
source "$HOME/.cargo/env.fish" # For fish
如果你想在当前终端直接使用 cargo 命令等,需要加载 ~/.cargo/env
文件。顺便也可以检查一下版本。
. "$HOME/.cargo/env"
cargo --version
输出内容
cargo 1.78.0 (54d8815d0 2024-03-26)
据说本月即将发布的1.80版本会有很多有趣的功能,比如cargo-script等。不过,现在我们还是以1.78.0版本为前提来进行接下来的学习吧!
虽然到这里看似准备工作已经完成了......但在Rust的编译过程中,我们还需要用到像gcc等C语言的编译环境。如果你是从一个全新安装的Ubuntu系统开始的话,可能会遇到如下错误。
$ cargo run
Compiling project v0.1.0 (/path/to/project)
error: linker `cc` not found
|
= note: No such file or directory (os error 2)
error: could not compile `project` (bin "project") due to 1 previous error
通过使用 apt
安装 build-essential
软件包,就可以安装gcc等必要的工具,这样就能顺利进行编译了。
sudo apt update
sudo apt install build-essential
另外,在使用 reqwest这个crate时,还需要安装 libssl-dev
等库。在进行Rust编程时,可能还会有其他需要提前安装的包,不过我们可以在练习过程中遇到需要时再逐一安装。
100 Exercises 导入
接下来,我们将引入 100-exercises-to-learn-rust。这个项目是通过 git
克隆的方式获取的。
git clone https://github.com/mainmatter/100-exercises-to-learn-rust.git
cd 100-exercises-to-learn-rust
git checkout -b my-solutions
这样一来,main分支的内容就会下载到本地。为了方便进度管理,我建议你在my-solutions
分支上进行管理,我也是这么做的。所有练习题都在exercises
目录下。
此外,据说solutions分支上有参考答案,如果在某些地方遇到困难,可以随时查看该分支的内容。
Workshop Runner 的安装
就像rustlings有专用的检查工具一样,100 Exercises 也有用于检查的工具。你可以通过 cargo install
命令来安装这个工具。
cargo install --locked workshop-runner
wr --help
输出内容
$ wr --help
A CLI to run test-driven Rust workshops
Usage: wr [OPTIONS] [COMMAND]
Commands:
open Open a specific exercise
help Print this message or the help of the given subcommand(s)
Options:
--no-skip ...
--verbose ...
--keep-going ...
-h, --help Print help
-V, --version Print version
这个工具似乎可以帮助你管理进度,解答完问题后可以使用它来更新进度。
编辑器选择
业界默认的标准组合是VSCode + rust-analyzer,因此我也会采用这个组合。rust-analyzer在安装后无需进行特别的配置,所以这里就不详细介绍了。
另外一个选择是最近正式发布的付费编辑器RustRover,感觉也不错。其实我对它很感兴趣
尝试挑战 第一题[01_intro/00_welcome]
到这里,环境已经顺利搭建完成,现在终于可以开始解题了。输入 wr
命令并选择"y",即可进入第一道题目。
$ wr
Running tests...
Eternity lies ahead of us, and behind. Your path is not yet finished. 🍂
Do you want to open the next exercise, (01) intro - (00) welcome? [y/n] y
Ahead of you lies (01) intro - (00) welcome
Open "exercises/01_intro/00_welcome" in your editor and get started!
Run `wr` again to compile the exercise and execute its tests.
打开 exercises/01_intro/00_welcome/src/lib.rs
文件,你会看到一些注释,其中提到以下内容:
//
表示单行注释。TODO
或todo!()
,以及__
,用于强调你需要在练习中完成的部分。- 代码的检查直接使用了Rust的标准测试机制(可以通过
cargo test
命令进行验证)。不过,wr
命令也可以替代这一过程。 - 请不要修改测试内容。
那么,让我们赶紧解决第一个问题,然后继续前进吧!
rust
fn greeting() -> &'static str {
// TODO: fix me 👇
"I'm ready to __!"
}
#[cfg(test)]
mod tests {
use crate::greeting;
#[test]
fn test_welcome() {
assert_eq!(greeting(), "I'm ready to learn Rust!");
}
}
带注释的版本
rust
// This is a Rust file. It is a plain text file with a `.rs` extension.
//
// Like most modern programming languages, Rust supports comments. You're looking at one right now!
// Comments are ignored by the compiler; you can leverage them to annotate code with notes and
// explanations.
// There are various ways to write comments in Rust, each with its own purpose.
// For now we'll stick to the most common one: the line comment.
// Everything from `//` to the end of the line is considered a comment.
// Exercises will include `TODO`, `todo!()` or `__` markers to draw your attention to the lines
// where you need to write code.
// You'll need to replace these markers with your own code to complete the exercise.
// Sometimes it'll be enough to write a single line of code, other times you'll have to write
// longer sections.
//
// If you get stuck for more than 10 minutes on an exercise, grab a trainer! We're here to help!
// You can also find solutions to all exercises in the `solutions` git branch.
fn greeting() -> &'static str {
// TODO: fix me 👇
"I'm ready to __!"
}
// Your solutions will be automatically verified by a set of tests.
// You can run these tests directly by invoking the `cargo test` command in your terminal,
// from the root of this exercise's directory. That's what the `wr` command does for you
// under the hood.
//
// Rust lets you write tests alongside your code.
// The `#[cfg(test)]` attribute tells the compiler to only compile the code below when
// running tests (i.e. when you run `cargo test`).
// You'll learn more about attributes and testing later in the course.
// For now, just know that you need to look for the `#[cfg(test)]` attribute to find the tests
// that will be verifying the correctness of your solutions!
//
// ⚠️ **DO NOT MODIFY THE TESTS** ⚠️
// They are there to help you validate your solutions. You should only change the code that's being
// tested, not the tests themselves.
#[cfg(test)]
mod tests {
use crate::greeting;
#[test]
fn test_welcome() {
assert_eq!(greeting(), "I'm ready to learn Rust!");
}
}
只要修改代码使测试通过,你就成功完成这一题了。
解说
这一题很简单,只需要将指定的字符串按照提示修改即可!
rust
fn greeting() -> &'static str {
// TODO: fix me 👇
- "I'm ready to __!"
+ "I'm ready to learn Rust!"
}
这里稍微解释一下:assert_eq!
是一个类似于函数的宏,它接受两个参数,并判断这两个参数是否相等。
由于这是"字符串的比较",对于习惯其他编程语言的人来说,可能会对这个过程有所警惕,但不用担心。大概在后面的章节中会提到,Rust 中的 ==
比较实际上是通过 eq 方法来实现的,对于字符串比较,它会从头开始逐字符进行比较,确保所有字符都相等。不会出现像检查指针是否相等这种直觉上不符合预期的比较方式。
解决问题后,你可以再次在项目根目录下运行 wr
命令,确认修改是正确的。
rust
$ wr
Running tests...
🚀 (01) intro - (00) welcome
Eternity lies ahead of us, and behind. Your path is not yet finished. 🍂
Do you want to open the next exercise, (01) intro - (01) syntax? [y/n] y
Ahead of you lies (01) intro - (01) syntax
Open "exercises/01_intro/01_syntax" in your editor and get started!
Run `wr` again to compile the exercise and execute its tests.
看起来一切都顺利!那我们继续挑战下一个问题吧!
下一篇文章: 【1】 语法、整数、变量