Rust 学习路线指南

作为一名 具有Go 后端技术栈的开发者,本文将帮助你理解 Rust 的核心概念、学习路径以及需要掌握的技术栈。

为什么选择 Rust?

Rust 是一门系统级编程语言,主打零成本抽象内存安全和** fearless concurrency**(无畏并发)。与 Go 相比,Rust 提供了更精细的资源控制能力和更强的编译时安全保障。

Rust vs Go 核心差异

特性 Go Rust
内存管理 GC(垃圾回收) 所有权系统 + 借用检查
性能 高性能,但有 GC 开销 接近 C 的性能,无运行时
并发 goroutine + channel 线程 + async/await
错误处理 if err != nil Result<T, E> + ? 运算符
泛型 2021 年才加入 一直支持,功能强大

阶段一:基础入门(1-2 周)

1.1 开发环境搭建

# 安装 Rust 工具链
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 验证安装
rustc --version  # 输出: rustc 1.xx.x
cargo --version  # 输出: cargo 1.xx.x

推荐 IDE:

  • VS Code + rust-analyzer 插件
  • RustRover(JetBrains 出品,学生免费)

1.2 基础语法

// Hello World
fn main() {
    println!("Hello, Rust!");
}

// 变量与可变性
let x = 5;          // 不可变
let mut y = 10;     // 可变
y += 1;

// 基本数据类型
let integer: i32 = 42;
let float: f64 = 3.14;
let boolean: bool = true;
let character: char = 'A';

// 函数定义
fn add(a: i32, b: i32) -> i32 {
    a + b  // 隐式返回(无分号)
}

// 控制流
if x > 0 {
    println!("positive");
} else {
    println!("non-positive");
}

// 循环
for i in 0..5 {
    println!("{}", i);
}

1.3 核心概念:所有权(Ownership)

这是 Rust 区别于 Go 的最核心概念。

fn main() {
    let s1 = String::from("hello");
    let s2 = s1;  // s1 所有权移动到 s2
    
    // println!("{}", s1);  // 错误:s1 已失效
    println!("{}", s2);    // 正常
    
    // 使用克隆来复制数据
    let s3 = String::from("world");
    let s4 = s3.clone();
    println!("{} {}", s3, s4);  // 两者都有效
}

1.4 借用(Borrowing)

fn main() {
    let s1 = String::from("hello");
    
    // 不可变借用
    let len = calculate_length(&s1);
    println!("{} 的长度是 {}", s1, len);  // s1 仍然有效
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

// 可变借用
fn main() {
    let mut s = String::from("hello");
    change(&mut s);
    println!("{}", s);  // 输出: hello, world
}

fn change(s: &mut String) {
    s.push_str(", world");
}

阶段二:核心概念进阶(2-3 周)

2.1 结构体与枚举

// 结构体
struct User {
    username: String,
    email: String,
    active: bool,
}

impl User {
    fn new(username: String, email: String) -> Self {
        User { username, email, active: true }
    }
    
    fn greet(&self) {
        println!("Hello, {}!", self.username);
    }
}

// 枚举与模式匹配
enum Result<T, E> {
    Ok(T),
    Err(E),
}

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
}

fn process_message(msg: Message) {
    match msg {
        Message::Quit => println!("Quit"),
        Message::Move { x, y } => println!("Move to ({}, {})", x, y),
        Message::Write(text) => println!("Write: {}", text),
    }
}

2.2 错误处理

use std::fs::File;
use std::io::{self, Read};

fn read_file(path: &str) -> Result<String, io::Error> {
    let mut file = File::open(path)?;  // ? 运算符传播错误
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

// 使用 match 处理错误
fn main() {
    match read_file("example.txt") {
        Ok(contents) => println!("File contents: {}", contents),
        Err(e) => println!("Error: {}", e),
    }
}

2.3 集合类型

// Vec 动态数组
let mut vec = Vec::new();
vec.push(1);
vec.push(2);
vec.push(3);

// HashMap 键值对
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert("Blue", 10);
scores.insert("Yellow", 50);

if let Some(score) = scores.get("Blue") {
    println!("Blue team: {}", score);
}

阶段三:特性和泛型(2-3 周)

3.1 Traits(特性)— 类似于 Go 的接口

trait Summary {
    fn summarize(&self) -> String;
    fn summarize_author(&self) -> String {
        String::from("(Unknown)")
    }
}

struct Article {
    title: String,
    author: String,
    content: String,
}

impl Summary for Article {
    fn summarize(&self) -> String {
        format!("{}, by {}", self.title, self.author)
    }
    
    fn summarize_author(&self) -> String {
        format!("@{}", self.author)
    }
}

// 特性约束
fn notify(item: &impl Summary) {
    println!("Breaking news: {}", item.summarize());
}

3.2 泛型

fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest = &list[0];
    for item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

struct Point<T, U> {
    x: T,
    y: U,
}

impl<T, U> Point<T, U> {
    fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
        Point { x: self.x, y: other.y }
    }
}

3.3 生命周期

// 生命周期标注
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

// 结构体中的生命周期
struct ImportantExcerpt<'a> {
    part: &'a str,
}

impl<'a> ImportantExcerpt<'a> {
    fn level(&self) -> i32 { 3 }
    
    fn announce_and_return(&self, announcement: &str) -> &str {
        println!("Attention: {}", announcement);
        self.part
    }
}

阶段四:并发编程(2 周)

4.1 线程

use std::thread;
use std::time::Duration;

fn main() {
    let handle = thread::spawn(|| {
        for i in 1..=5 {
            println!("Thread: {}", i);
            thread::sleep(Duration::from_millis(100));
        }
    });
    
    handle.join().unwrap();
    
    // 数据在线程间传递
    let v = vec![1, 2, 3];
    let handle = thread::spawn(move || {
        println!("Vector: {:?}", v);
    });
    handle.join().unwrap();
}

4.2 异步编程

use tokio;

#[tokio::main]
async fn main() {
    let result = fetch_data().await;
    println!("Result: {}", result);
}

async fn fetch_data() -> String {
    // 模拟异步操作
    "Data fetched".to_string()
}

// 并发执行多个任务
async fn concurrent_requests() {
    let task1 = tokio::spawn(async {
        fetch_data().await
    });
    
    let task2 = tokio::spawn(async {
        fetch_data().await
    });
    
    let (result1, result2) = tokio::join!(task1, task2);
    println!("{} {}", result1.unwrap(), result2.unwrap());
}

阶段五:项目实践与生态

5.1 必须掌握的工具

工具 用途
Cargo 包管理器 + 构建工具
rustfmt 代码格式化
Clippy 代码风格检查与建议
rust-analyzer LSP 语法分析器

5.2 常用 Crate

[dependencies]
tokio = { version = "1", features = ["full"] }  # 异步运行时
serde = { version = "1", features = ["derive"] }  # 序列化
serde_json = "1"  # JSON 处理
axum = "0.7"  # Web 框架
sqlx = "0.7"  # 数据库操作
tracing = "0.1"  # 日志
anyhow = "1"  # 错误处理
clap = "4"  # CLI 参数解析

5.3 推荐学习项目

初学者(1-2 周):

  • 命令行计算器
  • Todo CLI 应用
  • 文件加密/解密工具

中级(2-4 周):

  • REST API(使用 Axum/Actix)
  • 简单的 Web 服务器
  • JSON 解析器

高级(4+ 周):

  • 完整的博客系统
  • 微服务架构
  • 区块链项目(如学习 Solana/Polkadot)

阶段六:高级主题

6.1 智能指针

// Box<T> - 堆分配
let b = Box::new(5);

// Rc<T> - 引用计数
use std::rc::Rc;
let data = Rc::new(vec![1, 2, 3]);
let clone1 = Rc::clone(&data);
let clone2 = Rc::clone(&data);

// Arc<T> - 原子引用计数(线程安全)
use std::sync::Arc;
let data = Arc::new(vec![1, 2, 3]);
let handle = thread::spawn(move || {
    println!("{:?}", data);
});

6.2 宏编程

// 声明宏
macro_rules! vec {
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}

// 使用
let v = vec![1, 2, 3, 4];

6.3 Unsafe Rust 与 FFI

unsafe fn dangerous() {
    let mut num = 5;
    let r = &mut num as *mut i32;
    *r = 20;
}

// 外部函数接口
extern "C" {
    fn abs(input: i32) -> i32;
}

学习资源推荐

官方资源

  • The Rust Book - https://doc.rust-lang.org/book/
  • Rust by Example - https://doc.rust-lang.org/rust-by-example/
  • Rustlings - https://github.com/rust-lang/rustlings

进阶书籍

  • 《Programming Rust》(O’Reilly)
  • 《Rust for Rustaceans》
  • 《Zero To Production In Rust》

在线课程

  • RustCamp - 免费的 Rust 教程
  • No Boilerplate - YouTube 频道,优质 Rust 视频教程

总结

作为 Go 开发者,你已经具备了并发编程和现代语言的基础。Rust 的学习曲线主要集中在所有权系统生命周期上。一旦掌握这些概念,你会体会到 Rust 带来的安全性和性能优势。

建议的学习顺序:

  1. 基础语法 + 环境搭建
  2. 所有权与借用(最重要)
  3. 结构体、枚举、错误处理
  4. Traits 与泛型
  5. 并发与异步
  6. 项目实战

祝学习愉快!🦀


本文会持续更新,欢迎 Star收藏。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐