1. 安装 Rust

你可以在 Rust 演练场上在线试用 Rust 而无需在计算机上安装任何东西。

无需安装,直接尝试 RUST

本文系统环境:CentOS 8.2,其他非类 Unix 系统不适用本文。

1.1 Rustup: Rust 安装器和版本管理工具

安装 Rust 的主要方式是通过 Rustup 这一工具,它既是一个 Rust 安装器又是一个版本管理工具。

1
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

然后 Rustup 就都安装完成了。

这里说下 $HOME/.cargo/bin,也就是 ~/cargo/bin 这个目录。
在 Rust 开发环境中,所有工具都安装在 ~/.cargo/bin 目录中,你可以在这里找到包括 rustccargorustup 在内的 Rust 工具链,所以 Rust 开发者通常会将该目录加入 PATH 环境变量(上面的安装程序已经替我们做好了这件事)。但由于不同平台、命令行 Shell 之间存在差异,rustup 中也可能存在 Bug,因此在终端重启或用户重新登录之前,rustupPATH 的修改可能不会生效,甚至完全无效。

1.2 Rust 是最新的吗?

Rust 的升级非常频繁。如果你安装 Rustup 后已有一段时间,那么很可能你的 Rust 版本已经过时了。运行 rustup update 获取最新版本的 Rust。

1.3 Cargo: Rust 的构建工具和包管理器

你在安装 Rustup 时,也会安装 Rust 构建工具和包管理器的最新稳定版,即 Cargo。Cargo 可以做很多事情:

  • cargo build 可以构建项目;
  • cargo run 可以运行项目;
  • cargo test 可以测试项目;
  • cargo doc 可以为项目构建文档;
  • cargo publish 可以将库发布到 crates.io

要检查你是否安装了 Rust 和 Cargo,可以在终端中运行:

1
cargo --version

阅读《CARGO 手册》

1.4 其它工具

Rust 支持多种编辑器:

2. 创建新项目

因为这是第一个项目,我这里先不用任何第三方编辑器,
你可以用任意自己喜欢的方式、喜欢的工具来进行下面的操作。

我们将在新的 Rust 开发环境中编写一个小应用。首先用 Cargo 创建一个新项目。在你的终端中执行:

1
cargo new hello-rust

这会生成一个名为 hello-rust 的新目录,其中包含以下文件:

1
2
3
4
hello-rust
|- Cargo.toml
|- src
|- main.rs
  • Cargo.toml 为 Rust 的清单文件。其中包含了项目的元数据和依赖库。

  • src/main.rs 为编写应用代码的地方。

这个自动生成的 src/main.rs 的内容是下面这样的

1
2
fn main() {
println!("Hello, world!");

显而易见,这就是学习一门编程语言的惯例了,先输出 hello, world!

cargo new 会生成一个新的“Hello, world!”项目!我们可以进入新创建的目录中,执行下面的命令来运行此程序:

1
cargo run

你应该会在终端中看到如下内容:

1
2
3
4
5
$ cargo run
Compiling hello-rust v0.1.0 (/home/gukaifeng/hello-rust)
Finished dev [unoptimized + debuginfo] target(s) in 0.79s
Running `target/debug/hello-rust`
Hello, world!

这里的 /home/gukaifeng/hello-rust 是我的这个 Rust 项目目录。

现在我们就成功运行了第一个 Rust 程序,输出了 hello, world!

3. 添加依赖

现在我们来为应用添加依赖。你可以在 crates.io,即 Rust 包的仓库中找到所有类别的库。在 Rust 中,我们通常把包称作“crates”。

在本项目中,我们使用了名为 ferris-says 的库。

我们在 Cargo.toml 文件中 [dependencies] 的下方添加以下信息(从 crate 页面上获取):

1
ferris-says = "0.2"

之后的 Cargo.toml 的内容是下面这样的,供参考

1
2
3
4
5
6
7
8
9
[package]
name = "hello-rust"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ferris-says = "0.2"

接着运行:

1
cargo build

…之后 Cargo 就会安装该依赖,终端上会输出下面这样的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cargo build
Updating crates.io index
Downloaded smawk v0.3.1
Downloaded unicode-width v0.1.8
Downloaded textwrap v0.13.4
Downloaded ferris-says v0.2.1
Downloaded smallvec v0.4.5
Downloaded 5 crates (97.7 KB) in 2.20s
Compiling smawk v0.3.1
Compiling unicode-width v0.1.8
Compiling smallvec v0.4.5
Compiling textwrap v0.13.4
Compiling ferris-says v0.2.1
Compiling hello-rust v0.1.0 (/home/gukaifeng/hello-rust)
Finished dev [unoptimized + debuginfo] target(s) in 38.65s

运行此命令会创建一个新文件 Cargo.lock,该文件记录了本地所用依赖库的精确版本。

其实可以从上面输出信息中看到,安装 ferris-says 的时候还附带安装了一些其他的包。

打开 Cargo.lock 看看,有如下的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "ferris-says"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9515ec2dd9606ec230f6b2d1f25fd9e808a2f2af600143f7efe7e5865505b7aa"
dependencies = [
"smallvec",
"textwrap",
"unicode-width",
]

[[package]]
name = "hello-rust"
version = "0.1.0"
dependencies = [
"ferris-says",
]

[[package]]
name = "smallvec"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90c5e5fe535e48807ab94fc611d323935f39d4660c52b26b96446a7b33aef10"

[[package]]
name = "smawk"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"

[[package]]
name = "textwrap"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd05616119e612a8041ef58f2b578906cc2531a6069047ae092cfb86a325d835"
dependencies = [
"smawk",
"unicode-width",
]

[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"

这个 Cargo.lock 记录的内容还是挺清楚的,可以看到我们要安装的 ferris-says,依赖 smallvec, textwrap, unicode-width 这三个包,这三个包又依赖了其他几个包,这里就不接着说了。然后我发现我们的项目 hello-rust 也被视为了一个包,我们刚刚在 Cargo.tomal 添加了依赖 ferris-says,这个信息也被写在了这个文件里,优秀且严谨哦!

-

要使用我们刚刚安装的依赖库,写法和 C/C++ 差不多,比如在 main.rs 开始的位置加入

1
use ferris_says::say;

我们就可以使用 ferris-says crate 中导出的 say 函数了。

4. 一个 Rust 小应用

现在我们用新的依赖库编写一个小应用。
删掉 main.rs 中原来的代码(那只是个示例而已),然后写入以下代码:

1
2
3
4
5
6
7
8
9
10
11
use ferris_says::say; // from the previous step
use std::io::{stdout, BufWriter};

fn main() {
let stdout = stdout();
let message = String::from("Hello fellow Rustaceans!");
let width = message.chars().count();

let mut writer = BufWriter::new(stdout.lock());
say(message.as_bytes(), width, &mut writer).unwrap();
}

保存完毕后,我们可以输入以下命令来运行此应用:

1
cargo run

如果一切正确,你会看到该应用将以下内容打印到了屏幕上:

1
2
3
4
5
6
7
8
9
10
11
12
   Compiling hello-rust v0.1.0 (/home/gukaifeng/hello-rust)
Finished dev [unoptimized + debuginfo] target(s) in 1.07s
Running `target/debug/hello-rust`
__________________________
< Hello fellow Rustaceans! >
--------------------------
\
\
_~^~^~_
\) / o o \ (/
'_ - _'
/ '-----' \

前三行是 Cargo 输出的编译运行信息,后面的就是我们的程序输出的内容了。

完工,现在你已经是一名 Rustacean 了!