进阶 Steve Klabnik / Carol Nichols 著,KaiserY 中译 2026-09-13 14:34:35 · 2 阅读

第1章 入门指南

让我们开始 Rust 之旅吧!需要学习的内容有很多,但每段旅程都始于某处。在本章中,我们将讨论:

  • 在 Linux、macOS 和 Windows 上安装 Rust
  • 编写一个打印 Hello, world! 的程序
  • 使用 Rust 的包管理器和构建系统 cargo

安装

安装

第一步是安装 Rust。我们会通过 rustup 下载 Rust,这是一个管理 Rust 版本和相关工具的命令行工具。下载时需要联网。

注意:如果你出于某些理由倾向于不使用 rustup,请到 Rust 的其他安装方法页面 查看其它安装选项。

接下来的步骤会安装最新稳定版 Rust 编译器。Rust 的稳定性保证意味着,本书中所有能够编译的示例,在更新的 Rust 版本中也应继续能够编译。不同版本之间的输出可能略有差异,因为 Rust 经常会改进错误信息和警告。也就是说,按照这些步骤安装的任何较新的稳定版 Rust,都应该能正常配合本书内容使用。

命令行标记

本章和全书中,我们会展示一些在终端中使用的命令。所有需要输入到终端的行都以 $ 开头。你不需要输入 $ 字符;这里显示的 $ 字符表示命令行提示符,仅用于提示每行命令的起点。不以 $ 起始的行通常展示前一个命令的输出。另外,PowerShell 专用的示例会采用 > 而不是 $

在 Linux 或 macOS 上安装 rustup

如果你使用 Linux 或 macOS,打开终端并输入如下命令:

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

这条命令会下载一个脚本并启动 rustup 工具的安装,它会安装最新稳定版 Rust。过程中可能会提示你输入密码。如果安装成功,将会出现如下内容:

Rust is installed now. Great!

另外,你还需要一个 链接器(linker),它是 Rust 用来将编译输出连接成单个文件的程序。你很可能已经安装了它。如果遇到链接器错误,你应该安装一个 C 编译器,其中通常会包含链接器。C 编译器本身也很有用,因为一些常见的 Rust 包依赖 C 代码,因此需要 C 编译器。

在 macOS 上,你可以通过运行以下命令获得 C 语言编译器:

$ xcode-select --install

Linux 用户通常应根据自己发行版(distribution)的文档安装 GCC 或 Clang。比如,如果你使用 Ubuntu,可以安装 build-essential 包。

在 Windows 上安装 rustup

在 Windows 上,前往 https://www.rust-lang.org/tools/install 并按照说明安装 Rust。在安装过程中的某一步,你会被提示安装 Visual Studio。它提供了链接器以及编译程序所需的本地库。如果你在这一步需要更多帮助,请访问 https://rust-lang.github.io/rustup/installation/windows-msvc.html

本书的余下部分会使用能同时运行于 cmd.exe 和 PowerShell 的命令。如果存在特定差异,我们会解释使用哪一个。

故障排除(Troubleshooting)

要检查 Rust 是否安装正确,打开 shell 并输入:

$ rustc --version

你应该会看到已发布的最新稳定版的版本号、commit hash 和 commit 日期,格式如下:

rustc x.y.z (abcabcabc yyyy-mm-dd)

如果看到了这些信息,就说明 Rust 已经安装成功了!如果没有看到,请按下面的方法检查 Rust 是否在你的 %PATH% 系统变量中。

在 Windows CMD 中,请使用命令:

> echo %PATH%

在 PowerShell 中,请使用命令:

> echo $env:Path

在 Linux 和 macOS 中,请使用命令:

$ echo $PATH

如果这些都没问题但 Rust 仍然无法使用,还有很多地方可以求助。你可以在社区页面查看如何联系其他 Rustaceans(Rust 用户对自己的一个戏称)。

更新与卸载

通过 rustup 安装 Rust 之后,更新到新发布的版本很简单。只需要在 shell 中运行下面的更新脚本:

$ rustup update

若要卸载 Rust 和 rustup,请在 shell 中运行下面的卸载脚本:

$ rustup self uninstall

本地文档

安装 Rust 时也会附带一份文档的本地副本,供你离线阅读。运行 rustup doc 即可在浏览器中打开本地文档。

任何时候,如果标准库提供了某个类型或函数,而你不确定它是做什么的或该如何使用,请查阅应用程序接口(application programming interface,API)文档!

文本编辑器和集成开发环境(Integrated Development Environments, IDE)

本书不假设你使用什么工具来编写 Rust 代码。几乎任何文本编辑器都能胜任!不过,许多文本编辑器和集成开发环境(IDE)都内置了对 Rust 的支持。你总是可以在 Rust 官网的工具页面找到一个相对较新的常见编辑器和 IDE 列表。

离线使用本书

在一些示例中,我们会使用标准库之外的 Rust 包。要运行这些示例,你需要保持网络连接,或者提前下载好这些依赖。要预先下载依赖,可以运行以下命令。(稍后我们会详细解释 cargo 是什么,以及这些命令分别有什么作用。)

$ cargo new get-dependencies
$ cd get-dependencies
$ cargo add rand@0.8.5 trpl@0.2.0

这会把这些包下载并缓存起来,因此之后你就不需要再次下载它们了。运行完这些命令后,你无需保留 get-dependencies 文件夹。只要你执行过这些命令,在本书后续所有的 cargo 命令中,都可以使用 --offline 参数来使用这些已缓存的版本,而不必尝试联网。

Hello, World!

Hello, World!

既然安装好了 Rust,是时候来编写第一个 Rust 程序了。当学习一门新语言的时候,使用该语言在屏幕上打印 Hello, world! 是一项传统,我们将沿用这一传统!

注意:本书假设你熟悉基本的命令行操作。Rust 对于你的编辑器、工具,以及代码位于何处并没有特定的要求,如果你更倾向于使用集成开发环境(IDE),而不是命令行,请尽管使用你喜欢的 IDE。目前很多 IDE 都在一定程度上支持 Rust;查看 IDE 文档以了解更多细节。Rust 团队一直致力于借助 rust-analyzer 提供强大的 IDE 支持。详见附录 D

创建项目目录

首先创建一个存放 Rust 代码的目录。Rust 并不关心代码存放在哪里,不过对于本书中的练习和项目,我们建议你在 home 目录中创建一个 projects 目录,并将所有项目都放在那里。

打开终端并输入如下命令创建 projects 目录,并在 projects 目录中为 “Hello, world!” 项目创建一个目录。

对于 Linux、macOS 和 Windows PowerShell,输入:

$ mkdir ~/projects
$ cd ~/projects
$ mkdir hello_world
$ cd hello_world

对于 Windows CMD,输入:

> mkdir "%USERPROFILE%\projects"
> cd /d "%USERPROFILE%\projects"
> mkdir hello_world
> cd hello_world

Rust 程序基础

接下来,新建一个源文件,命名为 main.rs。Rust 文件总是以 .rs 扩展名结尾。如果文件名包含多个单词,那么按照命名习惯,应当使用下划线来分隔单词。例如应命名为 hello_world.rs,而不是 helloworld.rs

现在打开刚创建的 main.rs 文件,输入示例 1-1 中的代码。

文件名:main.rs

fn main() {
    println!("Hello, world!");
}
示例 1-1:一个打印 `Hello, world!` 的程序

保存文件,并回到当前目录为 ~/projects/hello_world 的终端窗口。在 Linux 或 macOS 上,输入如下命令,编译并运行文件:

$ rustc main.rs
$ ./main
Hello, world!

在 Windows 上,输入命令 .\main,而不是 ./main

> rustc main.rs
> .\main
Hello, world!

不管使用何种操作系统,终端应该打印字符串 Hello, world!。如果没有看到这些输出,回到安装部分的 “故障排除” 小节查找有帮助的方法。

如果 Hello, world! 确实打印出来了,恭喜你!你已经正式写出了一个 Rust 程序。现在你已经是一名 Rust 程序员了,欢迎加入!

Rust 程序的结构

现在,让我们回过头来仔细看看这个 “Hello, world!” 程序。这是第一块拼图:

fn main() {

}

这几行定义了一个名叫 main 的函数。main 函数很特殊:在每个可执行的 Rust 程序中,它都是最先运行的代码。这里第一行声明了一个名为 main 的函数,它没有参数也没有返回值。如果有参数,它们会写在小括号 () 中。

函数体被包裹在 {} 中。Rust 要求所有函数体都要用花括号包裹起来。一般来说,将左花括号与函数声明置于同一行并以空格分隔,是良好的代码风格。

注:如果你希望在 Rust 项目中保持一种标准风格,可以使用名为 rustfmt 的自动格式化工具将代码格式化为特定的风格(更多内容详见附录 D 中的 rustfmt)。Rust 团队已经在标准的 Rust 发行版中包含了这个工具,就像 rustc 一样。所以它应该已经安装在你的电脑中了!

main 函数体中有如下代码:

#![allow(unused)]
fn main() {
println!("Hello, world!");
}

这行代码完成这个简单程序的所有工作:在屏幕上打印文本。这里有三个重要的细节需要注意。

首先,println! 调用了一个 Rust 宏(macro)。如果调用的是函数,就应该写成 println(不带 !)。Rust 宏是一种用来编写可生成代码的代码,从而扩展 Rust 语法的方式;我们将在第二十章详细讨论宏。现在你只需要知道,看到 ! 就意味着调用的是宏而不是普通函数,并且宏并不总是遵循与函数相同的规则。

第二,"Hello, world!" 是一个字符串。我们把这个字符串作为一个参数传递给 println!,字符串将被打印到屏幕上。

第三,该行以分号结尾(;),这代表一个表达式的结束和下一个表达式可以开始。大部分 Rust 代码行以分号结尾。

编译与运行

你刚刚运行了一个新创建的程序,那么让我们检查此过程中的每一个步骤。

在运行 Rust 程序之前,必须先使用 Rust 编译器编译它,即输入 rustc 命令并传入源文件名称,如下:

$ rustc main.rs

如果你有 C 或 C++ 背景,就会发现这与 gccclang 类似。编译成功后,Rust 会输出一个二进制的可执行文件。

在 Linux、macOS,以及 Windows 的 PowerShell 上,你可以在 shell 中输入 ls 命令来查看这个可执行文件。

$ ls
main  main.rs

在 Linux 和 macOS,你会看到两个文件。在 Windows PowerShell 中,你会看到同使用 CMD 相同的三个文件。在 Windows 的 CMD 上,则输入如下命令:

> dir /B %= the /B option says to only show the file names =%
main.exe
main.pdb
main.rs

这展示了带有 .rs 扩展名的源代码文件、可执行文件(Windows 上是 main.exe,其他平台上则是 main),以及在 Windows 上一个带有 .pdb 扩展名、包含调试信息的文件。接下来,你可以运行 mainmain.exe,如下所示:

$ ./main # Windows 是 .\main.exe

如果这里的 main.rs 是上文所述的 “Hello, world!” 程序,那么在终端上就会打印出 Hello, world!

如果你更熟悉 Ruby、Python 或 JavaScript 这样的动态语言,可能不太习惯把编译和运行分成两个独立步骤。Rust 是一种 预先编译ahead-of-time compiled)语言,这意味着你可以先将程序编译好,再把可执行文件交给其他人;即使他们没有安装 Rust,也可以直接运行。如果你给别人的是一个 .rb.py.js 文件,他们就需要分别安装 Ruby、Python 或 JavaScript 的实现(运行时环境)。不过在这些语言中,编译和运行程序通常只需要一条命令。语言设计中的一切都是权衡取舍。

仅仅使用 rustc 编译简单程序是没问题的,不过随着项目的增长,你可能需要管理你项目的方方面面,并让代码易于分享。接下来,我们要介绍一个叫做 Cargo 的工具,它会帮助你编写真实世界中的 Rust 程序。

Hello, Cargo!

Hello, Cargo!

Cargo 是 Rust 的构建系统和包管理器。大多数 Rustaceans 都使用 Cargo 来管理他们的 Rust 项目,因为 Cargo 会替你处理许多任务,比如构建代码、下载代码依赖的库并编译这些库。(我们把代码所需要的库称为 依赖dependencies)。)

最简单的 Rust 程序,比如我们刚刚编写的那个,没有任何依赖。如果使用 Cargo 来构建 “Hello, world!” 项目,那么只会用到 Cargo 中负责构建代码的那部分功能。随着你编写更复杂的 Rust 程序,就会加入依赖项;如果项目一开始就是用 Cargo 创建的,那么添加依赖项会容易得多。

由于绝大多数 Rust 项目都使用 Cargo,本书接下来的部分也假设你会使用 Cargo。如果你使用的是 “安装” 部分介绍的官方安装方式,那么 Cargo 会随 Rust 一起安装。如果你通过其他方式安装 Rust,可以在终端输入如下命令检查是否安装了 Cargo:

$ cargo --version

如果你看到了版本号,说明 Cargo 已经安装好了!如果看到类似 command not found 的错误,你应该查阅相应安装方式的文档,确定如何单独安装 Cargo。

使用 Cargo 创建项目

我们使用 Cargo 创建一个新项目,然后看看与上面的 “Hello, world!” 项目有什么不同。回到 projects 目录(或者你存放代码的目录)。接着,可在任何操作系统下运行以下命令:

$ cargo new hello_cargo
$ cd hello_cargo

第一条命令会新建一个名为 hello_cargo 的目录和项目。我们将项目命名为 hello_cargo,Cargo 也会在同名目录中创建项目文件。

进入 hello_cargo 目录并列出文件。你会看到 Cargo 为我们生成了两个文件和一个目录:一个 Cargo.toml 文件、一个 src 目录,以及位于 src 目录中的 main.rs 文件。

它还会在 hello_cargo 目录中初始化一个 Git 仓库,并生成一个 .gitignore 文件。如果在一个已经存在的 Git 仓库中运行 cargo new,这些 Git 相关文件就不会再生成;你可以通过运行 cargo new --vcs=git 来覆盖这个行为。

注意:Git 是一种常见的版本控制系统(version control system,VCS)。你可以通过 --vcs 参数让 cargo new 使用其他版本控制系统,或者不使用 VCS。运行 cargo new --help 可以查看可用选项。

请自行选用文本编辑器打开 Cargo.toml 文件。它应该看起来与示例 1-2 中代码类似:

文件名:Cargo.toml

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2024"

[dependencies]
示例 1-2:`cargo new` 命令生成的 *Cargo.toml* 的内容

这个文件使用 TOMLTom’s Obvious, Minimal Language)格式,这是 Cargo 配置文件所使用的格式。

第一行 [package] 是一个 section 标题,表明下面的语句是在配置一个 package。随着我们在这个文件中加入更多信息,还会增加其他 section。

接下来的三行设置了 Cargo 编译程序所需的配置信息:项目名称、项目版本,以及要使用的 Rust edition。附录 E 会介绍 edition 这个键。

最后一行 [dependencies] 是列出项目依赖的 section 的开始。在 Rust 中,代码包被称为 crates。这个项目不需要其他 crate,不过在第二章的第一个项目中我们就会需要依赖,到时候会用到这个 section。

现在打开 src/main.rs 看看:

文件名:src/main.rs

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

Cargo 为你生成了一个 “Hello, world!” 程序,正如我们之前写的示例 1-1!到目前为止,我们的项目与 Cargo 生成的项目之间的区别在于:Cargo 将代码放在 src 目录中,并在项目根目录放置了一个 Cargo.toml 配置文件。

Cargo 期望你的源文件位于 src 目录中。项目根目录则只用来放 README、license 信息、配置文件,以及其他与代码无关的内容。使用 Cargo 有助于让项目保持整洁:各类文件各归其位。

如果你一开始没有使用 Cargo 创建项目,比如我们之前创建的 “Hello, world!” 项目,你也可以把它转换成一个使用 Cargo 的项目。只要把项目代码移到 src 目录中,并创建一个合适的 Cargo.toml 文件即可。一个简单的办法是运行 cargo init,它会自动为你创建这个文件。

构建并运行 Cargo 项目

现在让我们来看看,使用 Cargo 构建和运行 “Hello, world!” 程序有什么不同!在 hello_cargo 目录下,输入下面的命令来构建项目:

$ cargo build
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs

这条命令会在 target/debug/hello_cargo 生成一个可执行文件(Windows 上是 target\debug\hello_cargo.exe),而不是放在当前目录下。因为默认构建方式是调试构建(debug build),Cargo 会把可执行文件放在名为 debug 的目录中。你可以用下面的命令运行这个可执行文件:

$ ./target/debug/hello_cargo # 或者在 Windows 下为 .\target\debug\hello_cargo.exe
Hello, world!

如果一切顺利,终端上应该会打印出 Hello, world!。第一次运行 cargo build 时,Cargo 还会在项目根目录创建一个新文件:Cargo.lock。这个文件会记录项目依赖的精确版本。由于这个项目没有依赖,所以文件内容比较少。你永远都不需要手动修改这个文件;Cargo 会替你管理它的内容。

我们刚刚使用 cargo build 构建了项目,并使用 ./target/debug/hello_cargo 运行了程序;也可以使用 cargo run,在一条命令中完成编译并运行生成的可执行文件:

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_cargo`
Hello, world!

比起必须先运行 cargo build 再用可执行文件的完整路径来执行程序,使用 cargo run 更方便,所以大多数开发者会选择 cargo run

注意,这一次并没有出现表明 Cargo 正在编译 hello_cargo 的输出。Cargo 发现文件没有发生变化,所以它没有重新构建,而是直接运行了二进制文件。如果你修改了源文件,Cargo 就会在运行之前重新构建项目,并会出现像这样的输出:

$ cargo run
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
     Running `target/debug/hello_cargo`
Hello, world!

Cargo 还提供了一个叫 cargo check 的命令。该命令快速检查代码确保其可以编译,但并不产生可执行文件:

$ cargo check
   Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs

为什么你会不需要可执行文件呢?通常 cargo checkcargo build 快得多,因为它省略了生成可执行文件这一步。如果你在编写代码时持续检查,cargo check 可以让你更快知道当前代码是否还能正常编译!因此,很多 Rustaceans 都会在编写程序时定期运行 cargo check 来确保代码可以编译;等到准备好使用可执行文件时,再运行 cargo build

我们回顾下已学习的 Cargo 内容:

  • 可以使用 cargo new 创建项目。
  • 可以使用 cargo build 构建项目。
  • 可以使用 cargo run 一步构建并运行项目。
  • 可以使用 cargo check 在不生成二进制文件的情况下构建项目来检查错误。
  • 有别于将构建结果放在与源码相同的目录,Cargo 会将其放到 target/debug 目录。

使用 Cargo 的另一个优点是,不论你使用什么操作系统,这些命令都是相同的。所以从现在开始,本书将不再分别为 Linux、macOS 和 Windows 提供单独的命令。

发布(release)构建

当项目最终准备好发布时,可以使用 cargo build --release 以启用优化方式编译项目。这会在 target/release 而不是 target/debug 下生成可执行文件。这些优化会让 Rust 代码运行得更快,不过开启优化也会延长编译时间。这就是为什么会有两种不同的 profile:一种用于开发,你会希望它能快速且频繁地重新构建;另一种用于构建最终交付给用户的程序,这种程序不会频繁重新构建,但会希望它运行得尽可能快。如果你在做代码运行时间的基准测试,请务必运行 cargo build --release,并使用 target/release 下的可执行文件进行测试。

把 Cargo 当作习惯

对于简单项目,Cargo 相比直接使用 rustc 并不会带来太多额外价值,但随着程序变得更复杂,它的价值就会逐渐显现。一旦程序增长到由多个文件组成,或者需要其他依赖,让 Cargo 来协调构建过程就会容易得多。

尽管 hello_cargo 项目很简单,但它已经用上了许多你在后续 Rust 开发中会经常使用的真实工具。实际上,当你在任何已有项目上工作时,都可以使用如下命令,通过 Git 检出代码、进入项目目录并构建它:

$ git clone example.org/someproject
$ cd someproject
$ cargo build

关于更多 Cargo 的信息,请查阅 其文档

总结

你已经为继续 Rust 之旅做好准备了!在本章中,你学习了如何:

  • 使用 rustup 安装最新稳定版 Rust
  • 更新到较新的 Rust 版本
  • 打开本地安装的文档
  • 直接通过 rustc 编写并运行 Hello, world! 程序
  • 使用 Cargo 创建并运行新项目

现在正是通过构建一个更实在的程序来熟悉 Rust 代码读写的好时机。因此,在第二章中我们会构建一个猜数字游戏程序。如果你更想先学习 Rust 中常见的编程概念,请先阅读第三章,然后再回到第二章。

评论 (0)