前言
Rust 是一门非常有意思的语言,初学时觉得它别扭无比,熟练之后又想用它重构一切。
相比于 C/C++,Rust 同样适合底层开发。它不能简单地替代 C/C++,但在网络服务、命令行工具、嵌入式和高性能应用等场景中,确实是一个很值得考虑的选择。
当然,越是涉及底层,需要控制的细节就越多。Rust 虽然有安全可靠的内存模型和便利的包管理,但学习曲线依然不算平缓。
目前来看,Rust 的生态已经比较成熟,但不同方向的发展程度仍然不一样。
比如 GUI 方向目前还没有一个由官方主导、能够覆盖所有场景的统一框架,因此选型时需要多花一些时间。
但这并非无法解决。Rust 可以通过 FFI 调用 C 语言库,相关内容可以参考后文:Rust 与 C/C++ 互操作实战指南。
这意味着许多 C 库都可以通过绑定在 Rust 中使用;而C++ 库则通常需要额外的封装,不能简单理解为“拿来就能调用”。
例如可以使用 Rust 绑定的 FLTK、GTK,也可以了解 egui、iced、Tauri 等 Rust 生态中的方案。
如果你熟悉 Web 前端,也可以了解 Tauri:Tauri。
Rust 带来的代码安全和工程便利确实很有吸引力,但它和 C/C++ 仍会长期共存,具体选择要看项目的历史包袱、平台支持和团队经验。Windows、Linux、macOS 以及大量基础设施都积累了庞大的 C/C++ 代码,短时间内不可能全部替换。
同时需要注意:有 C/C++ 经验会更容易理解指针、栈和堆,但学习 Rust 并不要求必须先学过 C/C++。
对于刚刚入门编程的同学,先掌握变量、函数和命令行等基本概念,再学习 Rust 会更顺利:初识 C++。
Rust 简介
Rust 由 Graydon Hoare 在 2006 年开始作为个人项目开发,Mozilla 从 2009 年开始参与赞助。
第一个有版本号的 Rust 编译器于 2012 年 1 月发布。Rust 1.0 作为第一个稳定版本于 2015 年 5 月 15 日发布。
Rust 1.0 在 2015 年发布,到现在已经有了比较成熟的工具链和生态。网络服务、命令行工具和 WebAssembly 等方向发展得比较快,GUI 和部分嵌入式场景则仍然需要自己做好技术选型。
简单了解 Rust 的发展情况后,再来看看它为什么受到关注。相比于 C/C++,Rust 能为开发人员带来不少便利:
- 内存安全:
在 safe Rust 中,编译器会检查所有权、借用和生命周期,能够在编译阶段阻止空指针、悬垂指针和数据竞争问题。
rust也允许你写unsafe的代码,以维持对数据的完全掌控,但这也意味着各类C/C++中的问题也会随之出现、因此除非必要、一般不建议在rust中写unsafe代码。
相比之下,C/C++ 中的指针和内存问题通常需要开发者自己维护,尤其是在大型项目中,很容易因此产生各种 Bug。
- 高效性能:
Rust 具有与 C 和 C++ 相当的性能,同时提供了闭包和模式匹配等现代语言特性。这使得 Rust 很适合编写高性能、低延迟的系统级应用程序和库。
- 并发性:
Rust 的所有权系统和借用规则,可以在编译阶段发现一部分线程安全问题。它不会自动替你设计并发程序,但能让错误更早暴露出来。
- 社区支持:
Rust拥有活跃的社区,在crates上提供了许多开源库、工具和框架,可以大幅度提升开发效率。
C/C++ 同样拥有庞大的社区和成熟生态,只是不同库之间的构建方式和包管理方式不够统一。
- 统一包管理
C/C++ 中,使用第三方库时经常需要自己处理下载、安装和配置。
Rust 通过 Cargo 统一处理项目构建、依赖解析、测试和文档生成。它不能解决所有问题,某些库仍然需要系统组件或 C 编译器,但日常使用确实方便很多。
虽然目前也有 vcpkg 等不错的 C/C++ 包管理工具,但不同项目的使用方式仍然不完全统一。了解这个区别后,接下来直接动手创建一个项目,感受一下 Cargo 的工作方式。
安装 Rust 工具链
与 C/C++ 一样,Rust 也是一门编译型语言。Rust 源代码通常需要先编译成二进制程序,然后才能运行。Windows 系统中常见的 .exe 就是一种可执行程序,Linux 和 macOS 下的文件名和扩展名则不一定相同。
建议直接从 Rust 官网进入安装页面:Rust
Rust 官方推荐使用 rustup 管理工具链,而不是只安装一个固定版本的编译器:

Windows 用户可以下载 rustup-init.exe;如果使用 Linux 或 macOS,则按照官网提供的命令安装即可:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
如果使用 Windows,下载后运行安装程序,等待安装完成即可。如果没有安装 Visual Studio,还需要安装 Microsoft C++ Build Tools 和 Windows SDK。
安装完成后,重新打开终端,运行下面几个命令:
rustc --version
cargo --version
rustup show
能正常打印版本信息,就说明工具链已经安装成功了。如果不知道如何打开或进入控制台,可以参考文章:程序员必懂的常识
第一次使用可能会觉得有些疑惑:明明安装的是 Rust,这里怎么一直在使用 Cargo 命令呢?
简单来说,Rust 工具链中有几个经常遇到的命令:
rustc是 Rust 编译器;rustup用来安装和管理 Rust 工具链;cargo是构建工具和包管理器。
后面开发 Rust 项目时,使用最多的基本就是 Cargo。
第一个 Rust 程序
我们可以通过命令 cargo new project-name 来创建一个 Rust 项目。
比如运行 cargo new hello-world:

然后它就会为我们在当前目录中生成一个项目文件夹:

这里简单对其介绍一下:
.git:如果本机安装了 Git,Cargo 默认可能会初始化这个版本库,也可以通过--vcs none禁用。src:默认的源代码目录,二进制项目的入口通常是src/main.rs。.gitignore:告诉 Git 哪些文件不需要提交,通常会忽略target目录。Cargo.toml:项目清单,里面记录项目名称、版本、edition 和依赖等信息。target:编译产物目录,通常不提交到 Git。
这里的 Git 并不是 Rust 的一部分,而是一个通用的版本控制工具。比如知名的 GitHub 网站,就使用 Git 进行版本管理。不会使用 Git 的可以参考:Git 详解。
用记事本打开 Cargo.toml,就能看到下面这样的内容:

对于想要使用的库,可以直接写在 [dependencies] 项下面,后面我会再详细介绍。
至于 TOML 配置文件的格式,可以参考文章:TOML 格式详解。
然后来到存放 Rust 代码的 src 目录:

这里面默认有一个 main.rs 文件,其中后缀 .rs 是 Rust 源文件的后缀。对于二进制项目,它通常是程序的入口文件。
刚开始学习时先不要随意移动它。实际上,Cargo 也支持通过配置文件指定其他入口;库项目则通常使用 src/lib.rs。
同样,我们可以用记事本打开它:

这里写的是一个函数:
fn:Rust 中的关键字,代表后面定义的是一个函数。main:函数名称。对于二进制程序,main是默认的入口函数。():函数的参数列表,最简单的函数可以写成fn name() {}。{}:函数体,也就是这个函数要执行的代码。这里使用println!("Hello, world!");向终端打印一行文字。
println! 是 Rust 中的宏,用于向终端输出一行文字。
如果你学过 C/C++、Python、Java 等语言,前期可以直接把它当作一个 print 函数,只是要注意名称后面先有一个 !,然后才是 ()。
这里同时要注意,很多语句的结尾使用英文分号 ;。但 Rust 的代码块最后可以放一个表达式并省略分号,所以不能简单理解为“每一行都必须有分号”。
你也可以直接在下方编辑并运行这段代码,感受一下效果:
现在回到控制台,进入这个文件夹,然后运行这段代码试一试:
cargo run

然后就可以看到它成功运行并打印出 Hello, world!。
如果你学过 C/C++,会发现到目前为止,Rust 比 C/C++ 稍微复杂一点。毕竟 C/C++ 只需要一个源代码文件就能输出 Hello World,而 Rust 一开始就给我们生成了一个项目结构。
不过,项目结构正是 Cargo 方便的地方:代码、依赖和编译产物都有固定的位置,后面项目变大时会更容易管理。编译产物通常位于 target/debug 目录,Windows 下文件名一般以 .exe 结尾,Linux 和 macOS 下则不一定有扩展名:

如果直接双击这个程序,窗口可能会一闪而过。这不是程序没有运行,而是因为它打印完字符串后就立即结束了;在终端中运行则可以直接看到输出。
除了 cargo run,Cargo 还提供了几个常用命令。如果只想检查代码,可以使用:
cargo check
如果只想生成编译产物,则使用:
cargo build
它默认构建 Debug 版本,适合开发和调试。
发布程序时可以构建 Release 版本:
cargo build --release
它会使用更强的优化配置,运行速度和最终体积通常更适合发布,但具体结果还会受到链接方式和项目配置影响。

编辑器与开发工具
从上面我们可以看到,即使只用记事本也能开发,但那实在是太麻烦了。我们需要一个有代码提示、跳转和错误诊断的编辑器来提高效率。
个人推荐 VS Code,当然也可以根据自己的习惯选择其他编辑器。
可以从官网下载安装:VS Code

根据自己的系统选择合适的版本下载安装。
如果终端提示找不到 code 命令,需要重新打开终端,或者按照 VS Code 官方文档将命令加入 PATH。
在控制台中进入项目文件夹,然后输入:code .

这个 code 命令是 VS Code 提供的命令,用于让 VS Code 打开一个文件夹。
后面紧跟的 . 代表当前目录,也就是用 VS Code 打开当前项目目录。目录相关介绍可以参考文章:路径详解
然后你就能看到这个 Rust 项目在 VS Code 中被打开了:

但 VS Code 只是一个编辑器,所以还需要安装 Rust 插件来提供代码分析功能。
点击左边的插件选项,搜索并安装 rust-analyzer :

安装完成后,基本开发环境就配置好了。现在输入前几个字符时,就会自动弹出代码提示:

这时,你只需要按 Enter 键就可以自动帮你填充代码。
插件还会在 main 函数上方显示运行按钮。不过初学时建议同时熟悉 cargo run,这样换到其他编辑器也不会忘记基本操作。

如果需要断点调试,还需要编辑器和调试器配合,具体配置会因操作系统不同而有所区别:

不会调试的可以参考文章:调试。
初识 Cargo 包管理
熟悉项目的创建和运行之后,再来试一下 Rust 官方示例中的 ferris-says,看看 Cargo 添加第三方库有多方便。
比如,我们想要在终端打印出下面这个图案:

这里用到了 ferris-says 这个库。可以直接在终端运行:
cargo add ferris-says
也可以打开前面提到的 Cargo.toml,在 [dependencies] 项下面手动添加:

后面的数字是这个库的版本要求。添加完成后运行 cargo check 或 cargo run,Cargo 就会解析并下载依赖。
运行命令后,项目文件夹中还会多出一个 Cargo.lock 文件。
这个文件用于记录当前项目解析得到的精确依赖版本,由 Cargo 自动维护。应用项目一般应该把它提交到版本库。
虽然看上去它和 Cargo.toml 有些重复,但两者的作用并不一样。Cargo.toml 由开发者指定项目元信息和依赖版本范围。
而 Cargo.lock 文件则用来锁定依赖的具体版本。比如当你依赖了 A、B 两个库,而 A、B 内部又都依赖了 C 库,那么此时应该选择哪个 C 的版本呢?
这便是 Cargo.lock 所做的事了。Cargo 会根据规则选择 C 库的具体版本并记录下来,这样团队成员和 CI 就能尽量使用同一组依赖。
现在回到代码中使用这个库。下面这个可运行示例已经包含了 Cargo.toml 依赖配置和 src/main.rs——顶部可以切换文件,修改后点击运行即可:
第一次看到这段代码,你可能会感觉怎么有点复杂啊?
因为这一小段代码涉及到了 Rust 中相当多的概念,所以这里暂时不展开讲解。你可以先随意更改上面示例里的字符串:"Hello https://www.kucoding.com"
然后运行,就能在输出区看到图案了。
Cargo 下载的 crate 通常会缓存在当前用户的 ~/.cargo/registry 目录中,Git 依赖则会放在 ~/.cargo/git。当前项目的编译产物位于项目自己的 target 目录。

这些目录由 Cargo 管理,不建议手动修改里面的内容。
总结
这是该系列教程的第一章,主要介绍了 Rust 的特点、安装、项目结构、编辑器配置和代码运行。
主要有以下几个命令需要稍微记忆一下:
cargo new:新建一个 Rust 项目cargo check:快速检查代码cargo run:编译并运行代码cargo build:构建 Debug 版本cargo build --release:构建 Release 版本cargo fmt:格式化代码cargo clippy:检查常见问题并给出建议cargo test:运行测试
如果需要更新 Rust 工具链,运行下面的命令即可:
rustup update