Rust 是一门注重安全、并发与性能的系统级编程语言。本站后端即采用 Rust + Axum 构建,本教程帮助你快速上手 Rust,并理解本项目的代码组织方式。

为什么选择 Rust

  • 内存安全:编译期通过所有权系统消除悬垂指针、数据竞争
  • 高性能:无 GC,适合网络服务、爬虫、音视频处理等场景
  • 现代工具链cargo 统一管理依赖、构建、测试与发布
  • 异步生态成熟:Tokio + Axum 足以支撑生产级 Web 服务

环境安装

安装 Rustup

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

# Windows 请访问 https://www.rust-lang.org/tools/install 下载 rustup-init

安装完成后验证:

rustc --version
cargo --version

常用命令

命令作用
cargo new hello创建新项目
cargo build编译(debug)
cargo run编译并运行
cargo test运行测试
cargo check快速类型检查
cargo fmt格式化代码
cargo clippy静态分析与 lint

语言基础

变量与类型

let name = "LivisSnack";       // 不可变绑定
let mut count = 0;             // 可变绑定
count += 1;

let n: i32 = 42;
let price: f64 = 9.9;
let ok: bool = true;

所有权(Ownership)

Rust 最核心的概念:

let s1 = String::from("hello");
let s2 = s1;          // s1 所有权转移给 s2,s1 不再可用
// println!("{s1}");  // 编译错误

let s3 = String::from("world");
let s4 = s3.clone();  // 深拷贝,s3 仍可用

函数传参默认转移所有权;借用(引用)可避免拷贝:

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

结构体与枚举

struct Post {
title: String,
slug: String,
}

enum Status {
Ok,
NotFound,
Error(String),
}

配合 match 做穷尽分支:

fn handle(status: Status) {
match status {
Status::Ok => println!("success"),
Status::NotFound => println!("404"),
Status::Error(msg) => eprintln!("{msg}"),
}
}

错误处理

推荐使用 Result 而非 panic:

use std::fs;

fn read_config(path: &str) -> Result<String, std::io::Error> {
let content = fs::read_to_string(path)?;
Ok(content)
}

? 运算符在出错时自动向上返回错误。

异步编程

Rust 异步基于 async / .await,运行时需要 Tokio:

# Cargo.toml
[dependencies]
tokio = { version = "1", features = ["full"] }

示例:

use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
sleep(Duration::from_secs(1)).await;
println!("done");
}

并发请求常用 tokio::spawnfutures::future::join_all

Axum Web 框架

Axum 是本站使用的 HTTP 框架,基于 Tower 中间件生态。

最小示例

use axum::{routing::get, Router};

async fn hello() -> &'static str {
"Hello, Rust!"
}

#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(hello));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}

路由与 Handler

use axum::{extract::Path, Json};
use serde_json::{json, Value};

async fn get_post(Path(slug): Path<String>) -> Json<Value> {
Json(json!({ "slug": slug }))
}

路径参数、查询参数、请求体均可通过 extract 模块提取。

本项目结构导读

live_crawler 仓库主要目录:

src/
├── main.rs           # 入口,启动 HTTP 服务
├── blog/             # 博客:文章、页面、周刊、站点配置
├── routes/           # 路由注册与请求处理
├── templates.rs      # Minijinja 模板渲染
├── livesource/       # 直播源、CMS、新闻等业务模块
└── db.rs             # SQLite 数据库
blog/
├── posts/            # Markdown 文章
├── pages/            # 静态页面(教程、关于等)
├── weekly/           # 周刊
└── site.json         # 站点导航与社交配置

博客页面加载流程:

  1. 启动时 blog::mod 读取 blog/ 目录下的 Markdown 与 JSON
  2. routes/handlers.rs 根据 URL 匹配 handler
  3. templates.rs 将数据注入 Minijinja 模板并返回 HTML

本地开发:

cargo run
# 访问 http://127.0.0.1:8080

Docker 部署见项目根目录 Dockerfile

实战建议

  1. 先通读 Rust 程序设计语言 前 10 章
  2. cargo new 写几个小程序练手(文件读写、HTTP 请求)
  3. 阅读本站 src/blog/mod.rs,理解 Markdown 解析与缓存
  4. 尝试新增一篇博客文章或一个 API 路由
  5. 开启 cargo clippy 养成良好编码习惯

本站相关文章

延伸阅读