为什么是 Rust:从 Go 视角认识一门追求零成本抽象的语言

🔊

本文基于 Rust 1.82(2026-01-23 发布,当前最新稳定版)。Rust 是一门经过实战验证的现代系统编程语言,官方文档在 doc.rust-lang.org,安装指南在 rust-lang.org/tools/install/

为什么是 Rust?

如果你已经掌握了 Go,可能会问:为什么还要学 Rust?Rust 的存在是为了填补 Go 在性能和控制力上的空白。

Go 以极低的入门门槛、优秀的并发模型和快速的编译速度征服了云原生和微服务领域,但它的垃圾回收(GC)和固定运行时让它在系统编程、嵌入式和高性能场景中处处掣肘。当你需要更精细的内存控制、更低的延迟,或者在没有操作系统内核支持的嵌入式环境工作时,Go 的 GC 就成了负担。

Rust 追求接近 C/C++ 的性能与表达力,同时通过所有权系统在编译期保证内存安全,且不引入运行时开销。这意味着你可以写出接近 C 的性能,同时避免 C 中常见的内存安全问题。

Rust 的设计哲学

下面是 Rust 的几条核心设计原则,每一条都与 Go 形成对照。

零成本抽象(Zero-Cost Abstractions)。Rust 的口号是"抽象不应该带来运行时开销"。在 Go 中,interface{} 接口调用需要运行时类型断言,而 Rust 的 trait 机制在编译期完全静态化。你可以写出高层次的代码,但编译器会将其优化成与手写底层代码性能等价的机器码。对于习惯了 Go 的"简单胜于复杂"哲学的开发者来说,这需要理解:Rust 选择在编译期付出代价,换取运行时的高性能。

内存安全无 GC(Memory Safety without Garbage Collection)。Go 通过 GC 自动管理内存,开发者只需关注业务逻辑。Rust 则通过所有权(ownership)、借用(borrowing)和生命周期(lifetime)机制在编译期保证内存安全。你不需要在运行时等待 GC 暂停,但也需要在编码时思考内存的生命周期。这种权衡让 Rust 在嵌入式、实时系统和游戏开发等领域极具吸引力。

无畏并发(Fearless Concurrency)。Go 的 goroutine 和 channel 让并发变得简单,但数据竞争(data race)仍然可能在运行时发生。Rust 的类型系统在编译期就能捕获数据竞争,如果代码编译通过,你就不用担心线程安全问题。这种"编译期保证一切"的哲学是 Rust 最独特的卖点之一。

高性能工具链(High-Performance Toolchain)。Go 的编译器以速度著称,编译大型项目只需要几秒。Rust 的编译速度虽然不如 Go,但通过增量编译和并行编译,在现代硬件上已经可接受。更重要的是,Rust 的包管理器 Cargo 提供了依赖管理、测试、文档生成等一整套工具链,这比 Go 的 go mod + 手动脚本集成度更高。

Go vs Rust 核心对比

下面这张表可以帮助已经熟悉 Go 的你,快速定位 Rust 在技术谱系中的位置:

特性GoRust
内存管理垃圾回收(GC)所有权+借用检查
运行时有(goroutine 调度器、GC)无(零成本抽象)
错误处理多返回值(error)Result<T, E> 枚举
泛型有(1.18+)有(trait + 泛型参数)
并发编程goroutine+channelasync/await + std::thread
编译速度极快慢(但增量编译可接受)
学习曲线平缓陡峭

这张表不是要分高下,而是帮你定位:每个语言都有自己的设计取舍。Rust 选择了"在编译期捕获错误"的路线——没有 GC 意味着你需要理解所有权系统,没有运行时意味着你的程序就是二进制本身,Result 类型让你知道每个函数可能失败的点。

对于从 Go 转过来的开发者,最大的心智转变是内存管理:你需要理解所有权和借用的概念,并在代码中显式表达这些意图。这听起来很复杂,但 Rust 编译器会提供极其友好的错误提示,帮助你理解问题所在。

适用场景

Rust 特别适合以下场景:

  • 系统编程:操作系统内核、文件系统、网络协议栈
  • 嵌入式开发:在没有操作系统的裸金属设备上运行
  • WebAssembly:编译到 WASM 在浏览器中运行高性能代码
  • 高性能服务:需要低延迟、高吞吐量的后端服务
  • 游戏开发:游戏引擎、网络同步、物理模拟

相比之下,Go 更适合:

  • 云原生基础设施(Kubernetes、Docker)
  • 微服务和 API 服务
  • 命令行工具和小型实用程序
  • 快速原型和 MVP 开发

安装 Rust

Rust 的官方安装工具是 rustup,它不仅安装 Rust 编译器 rustc 和包管理器 cargo,还管理不同的 Rust 版本和目标平台。

使用 rustup 安装

在 macOS 和 Linux 上,执行:

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

在 Windows 上,下载并运行 rustup-init.exe

安装过程中,rustup 会询问一些配置选项。对于首次安装,选择默认选项(直接回车)即可。

安装完成后,重新加载你的 shell 配置:

bash
1
source $HOME/.cargo/env

验证安装:

bash
1
2
rustc --version
cargo --version

你应该会看到类似这样的输出:

1
2
rustc 1.82.0 (2026-01-23)
cargo 1.82.0

rustup toolchain 管理

Rustup 让你可以轻松切换不同版本的 Rust 工具链。例如,安装并使用最新 nightly 版本:

bash
1
2
rustup install nightly
rustup default nightly

或者查看所有已安装的工具链:

bash
1
rustup show

注意:对于学习阶段,建议使用 stable 工具链(默认安装)。Nightly 版本包含实验性特性,可能不稳定。

配置国内镜像(可选)

如果你在中国大陆,下载依赖可能较慢。可以配置国内镜像源。在 ~/.cargo/config 文件中添加:

toml
1
2
3
4
5
[source.crates-io]
replace-with = 'ustc'

[source.ustc]
registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"

Cargo 基础

Cargo 是 Rust 的包管理器和构建系统,它集成了依赖管理、编译、测试、文档生成等功能。相比 Go 的 go mod,Cargo 提供了更完整的开发生态。

创建新项目

使用 cargo new 创建一个新的 Rust 项目:

bash
1
2
cargo new hello_rust
cd hello_rust

这会创建一个标准的 Rust 项目结构:

1
2
3
4
hello_rust/
├── Cargo.toml      # 项目配置文件
└── src/
    └── main.rs     # 源代码文件

打开 Cargo.toml,你会看到类似这样的内容:

toml
1
2
3
4
5
6
[package]
name = "hello_rust"
version = "0.1.0"
edition = "2021"

[dependencies]

Cargo.toml 类似于 Go 的 go.mod,但功能更丰富。你可以在这里定义项目元数据、依赖版本、工作空间配置等。

构建和运行

在项目目录中,使用以下命令:

bash
1
2
3
cargo build      # 编译项目(debug 模式)
cargo run        # 编译并运行
cargo build --release  # 编译项目(release 模式,优化性能)

第一次运行 cargo build 时,Cargo 会下载并编译所有依赖。后续构建会使用增量编译,速度会快很多。

Hello World

打开 src/main.rs,你会看到 Cargo 已经为你生成了一个 Hello World 程序:

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

fn main() 是程序的入口点,类似于 Go 的 func main() { ... }println! 是一个宏(注意末尾的 !),它向标准输出打印格式化字符串。

运行程序:

bash
1
cargo run

你应该会看到输出:

1
Hello, world!

简单的 ownership 概念预告

在 Rust 中,所有权是最核心的概念之一。这里是一个简单的示例,让你先有个印象:

rust
1
2
3
4
5
6
7
fn main() {
    let s1 = String::from("hello");
    let s2 = s1;  // 所有权从 s1 转移到 s1

    // println!("{}", s1);  // 错误!s1 的所有权已经转移,不能再使用
    println!("{}", s2);  // 正确
}

在 Go 中,你可以随意复制字符串,因为 Go 的字符串是不可变的值类型,复制时只是复制了底层的指针和长度。但在 Rust 中,String 是可变的堆分配类型,它有所有权——同一时间只能有一个所有者。

当你把 s1 赋值给 s2 时,s1 的所有权"移动"到了 s2s1 就失效了。这就是 Rust 的"移动语义"(move semantics),它避免了内存的双重释放(double free)问题。

这个概念我们在后续章节会详细讲解,现在只需要知道:Rust 通过这种方式在编译期保证内存安全。

总结与下篇预告

在这一篇中,我们从 Go 视角认识了 Rust 的设计哲学、它在系统编程谱系中的定位,并安装了 Rust 工具链。总结几个关键结论:

  • Rust 填补了 Go(有 GC、运行时大)在系统编程和高性能场景下的空白
  • 核心设计理念:零成本抽象、内存安全无 GC、无畏并发、高性能工具链
  • 内存管理通过所有权系统实现,是 Go 开发者最需要适应的地方
  • rustup + Cargo 提供了完整的现代工具链
  • 所有权系统在编译期保证内存安全,避免了运行时 GC 的开销

下一篇我们将深入 Rust 的基础语法:变量、类型、函数和基本的控制流,以及与 Go 的核心差异点。我们会看到 Rust 如何通过类型系统和编译器检查,让你写出更安全的代码。


系列目录(六篇):

  1. 为什么是 Rust:从 Go 视角认识一门追求零成本抽象的语言(本篇)
  2. 基础语法:用 Go 经验快速上手 Rust —— 变量绑定、类型推断、match 表达式、Option
  3. 所有权与借用:Rust 的核心机制 —— move 语义、borrow checker、生命周期
  4. 错误处理:Result<T, E> 与 ? 运算符 —— 无 panic 的错误处理模式
  5. 结构体与 trait:抽象与组合 —— impl 块、trait 对象、trait bound
  6. 并发与异步:std::thread、async/await 和 tokio —— 从 goroutine 到 async 运行时