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::spawn 或 futures::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 # 站点导航与社交配置
博客页面加载流程:
- 启动时
blog::mod读取blog/目录下的 Markdown 与 JSON routes/handlers.rs根据 URL 匹配 handlertemplates.rs将数据注入 Minijinja 模板并返回 HTML
本地开发:
cargo run
# 访问 http://127.0.0.1:8080
Docker 部署见项目根目录 Dockerfile。
实战建议
- 先通读 Rust 程序设计语言 前 10 章
- 用
cargo new写几个小程序练手(文件读写、HTTP 请求) - 阅读本站
src/blog/mod.rs,理解 Markdown 解析与缓存 - 尝试新增一篇博客文章或一个 API 路由
- 开启
cargo clippy养成良好编码习惯
本站相关文章
- nodejs C++ 扩展 hello-world — 原生扩展与 FFI 思路,可与 Rust 对比阅读
- 揭秘 IPTV 代理技术及其实践应用 — 网络服务实战背景
- 前端编码规范示例 — 前后端协作时的接口与命名约定