Rust 程序设计语言的本质实际在于 赋能(empowerment):无论你现在编写的是何种代码,Rust 能让你在更为广泛的编程领域走得更远,写出自信。(这一点并不显而易见)
举例来说,那些“系统层面”的工作涉及内存管理、数据表示和并发等底层细节。从传统角度来看,这是一个神秘的编程领域,只为浸润多年的极少数人所触及,也只有他们能避开那些臭名昭著的陷阱。即使谨慎的实践者,亦唯恐代码出现漏洞、崩溃或损坏。
Rust 破除了这些障碍:它消除了旧的陷阱,并提供了伴你一路同行的友好、精良的工具。想要 “深入” 底层控制的程序员可以使用 Rust,无需时刻担心出现崩溃或安全漏洞,也无需因为工具链不靠谱而被迫去了解其中的细节。更妙的是,语言设计本身会自然而然地引导你编写出可靠的代码,并且运行速度和内存使用上都十分高效。
已经在从事编写底层代码的程序员可以使用 Rust 来提升信心。例如,在 Rust 中引入并行是相对低风险的操作,因为编译器会替你找到经典的错误。同时你可以自信地采取更加激进的优化,而不会意外引入崩溃或漏洞。
但 Rust 并不局限于底层系统编程。它表达力强、写起来舒适,让人能够轻松地编写出命令行应用、网络服务器等各种类型的代码。使用 Rust 能让你把在一个领域中学习的技能延伸到另一个领域:你可以通过编写网页应用来学习 Rust,接着将同样的技能应用到你的 Raspberry Pi(树莓派)上。
第一步是安装 Rust。我们会通过 rustup
下载 Rust,这是一个管理 Rust 版本和相关工具的命令行工具。下载时需要联网。
rust安装器下载地址:安装 Rust - Rust 程序设计语言
如果你使用 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 上,前往 https://www.rust-lang.org/install.html 并按照说明安装 Rust。在安装过程的某个步骤,你会收到一个信息说明为什么需要安装 Visual Studio 2013 或其更新版本的 MSVC 构建工具。
要获取构建工具,你需要安装 Visual Studio 2022。当被问及需要安装什么工作负载(Workload)的时候,请确保勾选了以下内容:
想要检查是否安装成功,可在命令行输入以下命令:
$ rustc --version
如果显示以下信息表明已经安装成功,显示的最新稳定版本的版本号、对应的 Commit Hash 和 Commit 日期
rustc x.y.z (abcabcabc yyyy-mm-dd)
如果没看到,请按照下面说明的方法检查 Rust 是否在您的 %PATH%
系统变量中。
在 Windows CMD 中,请使用命令:
> echo %PATH%
在 PowerShell 中,请使用命令:
> echo $env:Path
在 Linux 和 macOS 中,请使用命令:
$ echo $PATH
通过 rustup
安装了 Rust 之后,更新到最新版本就很简单了,只需要在您对应的命令行中运行如下更新脚本:
$ rustup update
若要卸载 Rust 和 rustup
,请在命令行中运行如下卸载脚本:
$ rustup self uninstall
对于 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
新建一个源文件,命名为 main.rs。Rust 源文件总是以 .rs 扩展名结尾。如果文件名包含多个单词,那么按照命名习惯,应当使用下划线来分隔单词。例如命名为 hello_world.rs,而不是 helloWorld.rs
打开创建的main.rs文件,输入以下代码
fn main() {
println!("Hello, world!");
}
保存文件,在当前文件位置打开终端。在 Linux 或 macOS 上,输入如下命令,编译并运行文件:
$ rustc main.rs
$ ./main
Hello, world!
在 Windows 上,输入命令 .\main.exe
,而不是 ./main
:
> rustc main.rs
> .\main.exe
Hello, world!
不管使用何种操作系统,终端应该打印字符串 Hello, world!
。这样就成功运行一个Rust程序了!
现在看看这个hello world的Rust程序,首先看看方法的外部:
fn main() {
}
这里是定义了一个名叫 main
的函数。main
函数是一个特殊的函数:在可执行的 Rust 程序中,它总是最先运行的代码。第一行代码声明了一个叫做 main
的函数,它没有参数也没有返回值。如果有参数的话,它们的名称应该写在小括号 ()
中。
函数体被包裹在 {}
中。Rust 要求所有函数体都要用花括号包裹起来。
在 main
函数中有如下代码:
println!("Hello, world!");
这行代码的作用是:在屏幕上打印文本。
然后,println!
调用了一个 Rust 宏(macro)。如果是调用函数,则应输入 println
(没有!
)。当看到符号 !
的时候,就意味着调用的是宏而不是普通函数,并且宏并不总是遵循与函数相同的规则。
"Hello, world!"
是一个字符串。我们把这个字符串作为一个参数传递给 println!
,字符串将被打印到屏幕上。
该行以分号结尾 ; ,这代表一个表达式的结束和下一个表达式的开始。大部分 Rust 代码行以分号结尾。
编译和运行是两个独立的步骤
在运行 Rust 程序之前,必须先使用 Rust 编译器编译它,即输入 rustc
命令并传入源文件名称,如下:
$ rustc main.rs
在 Linux、macOS 或 Windows 的 PowerShell 上,在 shell 中输入 ls
命令可以看见这个可执行文件。
$ ls
main main.rs
在 Linux 和 macOS,你会看到两个文件。在 Windows PowerShell 中,你会看到同使用 CMD 相同的三个文件,如以下内容:
> dir /B %= the /B option says to only show the file names =%
main.exe
main.pdb
main.rs
这展示了扩展名为 .rs 的源文件、可执行文件(在 Windows 下是 main.exe,其它平台是 main),以及当使用 CMD 时会有一个包含调试信息、扩展名为 .pdb 的文件。从这里开始运行 main 或 main.exe 文件,如下:
$ ./main # Windows 是 .\main.exe
Rust 是一种 预编译静态类型(ahead-of-time compiled)语言,这意味着你可以编译程序,并将可执行文件送给其他人,他们甚至不需要安装 Rust 就可以运行。
Cargo 是 Rust 的构建系统和包管理器。大多数 Rustacean 们使用 Cargo 来管理他们的 Rust 项目,因为它可以为你处理很多任务,比如构建代码、下载依赖库并编译这些库。
可以通过以下代码检查是否安装了Cargo
$ cargo --version
在文件目录打开命令行工具,输入以下命令:
$ cargo new hello_cargo
$ cd hello_cargo
这样我们就创建了hello_cargo的项目目录并进入项目
项目目录内生成了两个文件和一个目录:一个 Cargo.toml 文件,一个 src 目录,以及位于 src 目录中的 main.rs 文件。
任意编辑器打开Cargo.toml
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
这个文件使用 TOML (Tom's Obvious, Minimal Language) 格式,这是 Cargo 配置文件的格式。
第一行,[package]
,是一个片段(section)标题,表明下面的语句用来配置一个包。随着我们在这个文件增加更多的信息,还将增加其他片段(section)。
接下来的三行设置了 Cargo 编译程序所需的配置:项目的名称、项目的版本以及要使用的 Rust 版本。
最后一行,[dependencies]
,是罗列项目依赖的片段的开始。在 Rust 中,代码包被称为 crates。这个项目并不需要其他的 crate,不过在第二章的第一个项目会用到依赖,那时会用得上这个片段。
打开src/main.rs
fn main() {
println!("Hello, world!");
}
这个就是第二步创建的程序方法。
Cargo 生成的项目,将代码放在 src 目录,同时项目根目录包含一个 Cargo.toml 配置文件。
项目根目录只存放 README、license 信息、配置文件和其他跟代码无关的文件。使用 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),而不是放在目前目录下。
接下来可输入以下命令运行项目:
$ ./target/debug/hello_cargo # 或者在 Windows 下为 .\target\debug\hello_cargo.exe
如果一切顺利,终端上应该会打印出 Hello, world!
。
首次运行 cargo build
时,也会使 Cargo 在项目根目录创建一个新文件:Cargo.lock。这个文件记录项目依赖的实际版本。
使用文件目录名去运行项目比较麻烦,所以推荐使用以下命令可以同时编译并运行生产的可执行文件:
$ cargo run
返回:
Finished dev [unoptimized + debuginfo] target(s) in 0.0 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 new
创建项目。cargo build
构建项目。cargo run
一步构建并运行项目。cargo check
在不生成二进制文件的情况下构建项目来检查错误。当项目最终准备好发布时,可以使用 cargo build --release
来优化编译项目。这会在 target/release 而不是 target/debug 下生成可执行文件。这些优化可以让 Rust 代码运行的更快,不过启用这些优化也需要消耗更长的编译时间。