microsoft-rust-training
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMicrosoft Rust Training
Microsoft Rust 培训课程
Skill by ara.so — Daily 2026 Skills collection.
A collection of seven structured Rust training books maintained by Microsoft, covering Rust from multiple entry points (C/C++, C#/Java, Python backgrounds) through deep dives on async, advanced patterns, type-level correctness, and engineering practices. Each book contains 15–16 chapters with Mermaid diagrams, editable Rust playgrounds, and exercises.
来自 ara.so 的技能 — 2026每日技能合集。
这是微软维护的一套结构化Rust培训丛书,共七本,涵盖了从不同编程语言背景(C/C++、C#/Java、Python)入门Rust,到深入讲解异步编程、高级模式、类型级正确性以及工程实践的内容。每本书包含15-16个章节,配有Mermaid图表、可编辑的Rust在线编程环境和练习。
Book Catalog
丛书目录
| Book | Level | Focus |
|---|---|---|
| 🟢 Bridge | Move semantics, RAII, FFI, embedded, no_std |
| 🟢 Bridge | C#/Java/Swift → ownership & type system |
| 🟢 Bridge | Dynamic → static typing, GIL-free concurrency |
| 🔵 Deep Dive | Tokio, streams, cancellation safety |
| 🟡 Advanced | Pin, allocators, lock-free structures, unsafe |
| 🟣 Expert | Type-state, phantom types, capability tokens |
| 🟤 Practices | Build scripts, cross-compilation, CI/CD, Miri |
| 书籍 | 难度 | 重点内容 |
|---|---|---|
| 🟢 过渡 | 移动语义、RAII、FFI、嵌入式开发、no_std |
| 🟢 过渡 | C#/Java/Swift → 所有权与类型系统 |
| 🟢 过渡 | 动态类型 → 静态类型、无GIL并发 |
| 🔵 深入 | Tokio、流、取消安全 |
| 🟡 进阶 | Pin、分配器、无锁结构、unsafe代码 |
| 🟣 专家 | 类型状态、幽灵类型、能力令牌 |
| 🟤 实践 | 构建脚本、交叉编译、CI/CD、Miri |
Installation & Setup
安装与配置
Prerequisites
前置条件
bash
undefinedbash
undefinedInstall Rust via rustup
通过rustup安装Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Install mdBook and Mermaid preprocessor
安装mdBook和Mermaid预处理器
cargo install mdbook mdbook-mermaid
undefinedcargo install mdbook mdbook-mermaid
undefinedClone and Build
克隆与构建
bash
git clone https://github.com/microsoft/RustTraining.git
cd RustTrainingbash
git clone https://github.com/microsoft/RustTraining.git
cd RustTrainingBuild all books into site/
将所有书籍构建到site/目录
cargo xtask build
cargo xtask build
Serve all books locally at http://localhost:3000
cargo xtask serve
cargo xtask serve
Build for GitHub Pages deployment (outputs to docs/)
构建用于GitHub Pages部署的版本(输出到docs/)
cargo xtask deploy
cargo xtask deploy
Clean build artifacts
清理构建产物
cargo xtask clean
undefinedcargo xtask clean
undefinedServe a Single Book
单独服务某一本书籍
bash
cd c-cpp-book && mdbook serve --open # http://localhost:3000
cd python-book && mdbook serve --open
cd async-book && mdbook serve --openbash
cd c-cpp-book && mdbook serve --open # http://localhost:3000
cd python-book && mdbook serve --open
cd async-book && mdbook serve --openRepository Structure
仓库结构
RustTraining/
├── c-cpp-book/
│ ├── book.toml
│ └── src/
│ ├── SUMMARY.md # Table of contents
│ └── *.md # Chapter files
├── csharp-book/
├── python-book/
├── async-book/
├── rust-patterns-book/
├── type-driven-correctness-book/
├── engineering-book/
├── xtask/ # Build automation (cargo xtask)
│ └── src/main.rs
├── docs/ # GitHub Pages output
├── site/ # Local preview output
└── .github/workflows/
└── pages.yml # Auto-deploy on push to masterRustTraining/
├── c-cpp-book/
│ ├── book.toml
│ └── src/
│ ├── SUMMARY.md # 目录
│ └── *.md # 章节文件
├── csharp-book/
├── python-book/
├── async-book/
├── rust-patterns-book/
├── type-driven-correctness-book/
├── engineering-book/
├── xtask/ # 构建自动化(cargo xtask)
│ └── src/main.rs
├── docs/ # GitHub Pages输出目录
├── site/ # 本地预览输出目录
└── .github/workflows/
└── pages.yml # 推送到master分支时自动部署mdBook Configuration (book.toml
)
book.tomlmdBook配置(book.toml
)
book.tomlEach book contains a . Example configuration pattern:
book.tomltoml
[book]
title = "Async Rust"
authors = ["Microsoft"]
language = "en"
src = "src"
[build]
build-dir = "../site/async-book"
[preprocessor.mermaid]
command = "mdbook-mermaid"
[output.html]
default-theme = "navy"
preferred-dark-theme = "navy"
git-repository-url = "https://github.com/microsoft/RustTraining"
edit-url-template = "https://github.com/microsoft/RustTraining/edit/master/{path}"
[output.html.search]
enable = true每本书都包含一个文件。示例配置如下:
book.tomltoml
[book]
title = "Async Rust"
authors = ["Microsoft"]
language = "en"
src = "src"
[build]
build-dir = "../site/async-book"
[preprocessor.mermaid]
command = "mdbook-mermaid"
[output.html]
default-theme = "navy"
preferred-dark-theme = "navy"
git-repository-url = "https://github.com/microsoft/RustTraining"
edit-url-template = "https://github.com/microsoft/RustTraining/edit/master/{path}"
[output.html.search]
enable = trueKey Rust Concepts Covered by Book
各书籍涵盖的核心Rust概念
Bridge: Rust for C/C++ Programmers
过渡篇:面向C/C++开发者的Rust
Ownership & Move Semantics
rust
// C++ has copy by default; Rust moves by default
fn take_ownership(s: String) {
println!("{s}");
} // s is dropped here
fn main() {
let s = String::from("hello");
take_ownership(s);
// println!("{s}"); // ERROR: s was moved
// Use clone for explicit deep copy
let s2 = String::from("world");
let s3 = s2.clone();
println!("{s2} {s3}"); // Both valid
}RAII — No Manual Memory Management
rust
use std::fs::File;
use std::io::{self, Write};
fn write_data(path: &str, data: &[u8]) -> io::Result<()> {
let mut file = File::create(path)?; // Opens file
file.write_all(data)?;
Ok(())
} // file automatically closed here — no explicit close neededFFI Example
rust
// Calling C from Rust
extern "C" {
fn abs(x: i32) -> i32;
}
fn main() {
unsafe {
println!("abs(-5) = {}", abs(-5));
}
}所有权与移动语义
rust
// C++默认是拷贝;Rust默认是移动
fn take_ownership(s: String) {
println!("{s}");
} // s在此处被销毁
fn main() {
let s = String::from("hello");
take_ownership(s);
// println!("{s}"); // 错误:s已被移动
// 使用clone进行显式深拷贝
let s2 = String::from("world");
let s3 = s2.clone();
println!("{s2} {s3}"); // 两者均有效
}RAII — 无需手动内存管理
rust
use std::fs::File;
use std::io::{self, Write};
fn write_data(path: &str, data: &[u8]) -> io::Result<()> {
let mut file = File::create(path)?; // 打开文件
file.write_all(data)?;
Ok(())
} // 文件在此处自动关闭 — 无需显式调用closeFFI示例
rust
// 从Rust调用C代码
extern "C" {
fn abs(x: i32) -> i32;
}
fn main() {
unsafe {
println!("abs(-5) = {}", abs(-5));
}
}Bridge: Rust for Python Programmers
过渡篇:面向Python开发者的Rust
Static Typing with Type Inference
rust
// Python: x = [1, 2, 3]
// Rust infers the type from usage:
let mut numbers = Vec::new();
numbers.push(1_i32);
numbers.push(2);
numbers.push(3);
// Explicit when needed:
let numbers: Vec<i32> = vec![1, 2, 3];Error Handling (no exceptions)
rust
use std::num::ParseIntError;
fn double_number(s: &str) -> Result<i32, ParseIntError> {
let n = s.trim().parse::<i32>()?; // ? propagates error
Ok(n * 2)
}
fn main() {
match double_number("5") {
Ok(n) => println!("Doubled: {n}"),
Err(e) => println!("Error: {e}"),
}
}GIL-Free Concurrency
rust
use std::thread;
use std::sync::{Arc, Mutex};
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap()); // 10
}带类型推导的静态类型
rust
// Python: x = [1, 2, 3]
// Rust根据使用场景推导类型:
let mut numbers = Vec::new();
numbers.push(1_i32);
numbers.push(2);
numbers.push(3);
// 需要时可以显式指定类型:
let numbers: Vec<i32> = vec![1, 2, 3];错误处理(无异常)
rust
use std::num::ParseIntError;
fn double_number(s: &str) -> Result<i32, ParseIntError> {
let n = s.trim().parse::<i32>()?; // ? 用于传播错误
Ok(n * 2)
}
fn main() {
match double_number("5") {
Ok(n) => println!("翻倍后: {n}"),
Err(e) => println!("错误: {e}"),
}
}无GIL并发
rust
use std::thread;
use std::sync::{Arc, Mutex};
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("结果: {}", *counter.lock().unwrap()); // 10
}Deep Dive: Async Rust
深入篇:异步Rust
Basic Async with Tokio
rust
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let result = fetch_data().await;
println!("{result}");
}
async fn fetch_data() -> String {
sleep(Duration::from_millis(100)).await;
"data loaded".to_string()
}Concurrent Tasks
rust
use tokio::task;
#[tokio::main]
async fn main() {
let (a, b) = tokio::join!(
task::spawn(async { expensive_computation(1).await }),
task::spawn(async { expensive_computation(2).await }),
);
println!("{} {}", a.unwrap(), b.unwrap());
}
async fn expensive_computation(n: u64) -> u64 {
tokio::time::sleep(std::time::Duration::from_millis(n * 100)).await;
n * 42
}Cancellation-Safe Streams
rust
use tokio_stream::{self as stream, StreamExt};
#[tokio::main]
async fn main() {
let mut s = stream::iter(vec![1, 2, 3, 4, 5]);
while let Some(value) = s.next().await {
println!("got {value}");
}
}基于Tokio的基础异步编程
rust
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let result = fetch_data().await;
println!("{result}");
}
async fn fetch_data() -> String {
sleep(Duration::from_millis(100)).await;
"数据加载完成".to_string()
}并发任务
rust
use tokio::task;
#[tokio::main]
async fn main() {
let (a, b) = tokio::join!(
task::spawn(async { expensive_computation(1).await }),
task::spawn(async { expensive_computation(2).await }),
);
println!("{} {}", a.unwrap(), b.unwrap());
}
async fn expensive_computation(n: u64) -> u64 {
tokio::time::sleep(std::time::Duration::from_millis(n * 100)).await;
n * 42
}取消安全的流
rust
use tokio_stream::{self as stream, StreamExt};
#[tokio::main]
async fn main() {
let mut s = stream::iter(vec![1, 2, 3, 4, 5]);
while let Some(value) = s.next().await {
println!("收到 {value}");
}
}Advanced: Rust Patterns
进阶篇:Rust模式
Type-Safe Builder Pattern
rust
#[derive(Debug)]
struct Config {
host: String,
port: u16,
max_connections: usize,
}
struct ConfigBuilder {
host: String,
port: u16,
max_connections: usize,
}
impl ConfigBuilder {
fn new() -> Self {
Self {
host: "localhost".into(),
port: 8080,
max_connections: 100,
}
}
fn host(mut self, h: impl Into<String>) -> Self { self.host = h.into(); self }
fn port(mut self, p: u16) -> Self { self.port = p; self }
fn max_connections(mut self, m: usize) -> Self { self.max_connections = m; self }
fn build(self) -> Config {
Config { host: self.host, port: self.port, max_connections: self.max_connections }
}
}
fn main() {
let config = ConfigBuilder::new()
.host("0.0.0.0")
.port(9090)
.max_connections(500)
.build();
println!("{config:?}");
}Custom Allocator
rust
use std::alloc::{GlobalAlloc, Layout, System};
use std::sync::atomic::{AtomicUsize, Ordering};
static ALLOCATED: AtomicUsize = AtomicUsize::new(0);
struct TrackingAllocator;
unsafe impl GlobalAlloc for TrackingAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
ALLOCATED.fetch_add(layout.size(), Ordering::Relaxed);
System.alloc(layout)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
ALLOCATED.fetch_sub(layout.size(), Ordering::Relaxed);
System.dealloc(ptr, layout)
}
}
#[global_allocator]
static A: TrackingAllocator = TrackingAllocator;
fn main() {
let _v: Vec<u8> = vec![0u8; 1024];
println!("Allocated: {} bytes", ALLOCATED.load(Ordering::Relaxed));
}类型安全的构建器模式
rust
#[derive(Debug)]
struct Config {
host: String,
port: u16,
max_connections: usize,
}
struct ConfigBuilder {
host: String,
port: u16,
max_connections: usize,
}
impl ConfigBuilder {
fn new() -> Self {
Self {
host: "localhost".into(),
port: 8080,
max_connections: 100,
}
}
fn host(mut self, h: impl Into<String>) -> Self { self.host = h.into(); self }
fn port(mut self, p: u16) -> Self { self.port = p; self }
fn max_connections(mut self, m: usize) -> Self { self.max_connections = m; self }
fn build(self) -> Config {
Config { host: self.host, port: self.port, max_connections: self.max_connections }
}
}
fn main() {
let config = ConfigBuilder::new()
.host("0.0.0.0")
.port(9090)
.max_connections(500)
.build();
println!("{config:?}");
}自定义分配器
rust
use std::alloc::{GlobalAlloc, Layout, System};
use std::sync::atomic::{AtomicUsize, Ordering};
static ALLOCATED: AtomicUsize = AtomicUsize::new(0);
struct TrackingAllocator;
unsafe impl GlobalAlloc for TrackingAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
ALLOCATED.fetch_add(layout.size(), Ordering::Relaxed);
System.alloc(layout)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
ALLOCATED.fetch_sub(layout.size(), Ordering::Relaxed);
System.dealloc(ptr, layout)
}
}
#[global_allocator]
static A: TrackingAllocator = TrackingAllocator;
fn main() {
let _v: Vec<u8> = vec![0u8; 1024];
println!("已分配: {} 字节", ALLOCATED.load(Ordering::Relaxed));
}Expert: Type-Driven Correctness
专家篇:类型驱动的正确性
Typestate Pattern
rust
use std::marker::PhantomData;
struct Locked;
struct Unlocked;
struct Safe<State> {
contents: String,
_state: PhantomData<State>,
}
impl Safe<Locked> {
fn new(contents: impl Into<String>) -> Self {
Safe { contents: contents.into(), _state: PhantomData }
}
fn unlock(self, _key: &str) -> Safe<Unlocked> {
Safe { contents: self.contents, _state: PhantomData }
}
}
impl Safe<Unlocked> {
fn get_contents(&self) -> &str { &self.contents }
fn lock(self) -> Safe<Locked> {
Safe { contents: self.contents, _state: PhantomData }
}
}
fn main() {
let safe = Safe::<Locked>::new("secret data");
// safe.get_contents(); // ERROR: method not available on Locked state
let open = safe.unlock("correct-key");
println!("{}", open.get_contents());
let _locked_again = open.lock();
}Phantom Types for Unit Safety
rust
use std::marker::PhantomData;
struct Meters;
struct Feet;
struct Distance<Unit> {
value: f64,
_unit: PhantomData<Unit>,
}
impl<Unit> Distance<Unit> {
fn new(value: f64) -> Self {
Distance { value, _unit: PhantomData }
}
fn value(&self) -> f64 { self.value }
}
impl Distance<Meters> {
fn to_feet(self) -> Distance<Feet> {
Distance::new(self.value * 3.28084)
}
}
fn main() {
let d_m: Distance<Meters> = Distance::new(100.0);
let d_f: Distance<Feet> = d_m.to_feet();
println!("{:.2} feet", d_f.value());
// Can't mix units — type system prevents it
}类型状态模式
rust
use std::marker::PhantomData;
struct Locked;
struct Unlocked;
struct Safe<State> {
contents: String,
_state: PhantomData<State>,
}
impl Safe<Locked> {
fn new(contents: impl Into<String>) -> Self {
Safe { contents: contents.into(), _state: PhantomData }
}
fn unlock(self, _key: &str) -> Safe<Unlocked> {
Safe { contents: self.contents, _state: PhantomData }
}
}
impl Safe<Unlocked> {
fn get_contents(&self) -> &str { &self.contents }
fn lock(self) -> Safe<Locked> {
Safe { contents: self.contents, _state: PhantomData }
}
}
fn main() {
let safe = Safe::<Locked>::new("机密数据");
// safe.get_contents(); // 错误:Locked状态下无法调用该方法
let open = safe.unlock("正确密钥");
println!("{}", open.get_contents());
let _locked_again = open.lock();
}用于单位安全的幽灵类型
rust
use std::marker::PhantomData;
struct Meters;
struct Feet;
struct Distance<Unit> {
value: f64,
_unit: PhantomData<Unit>,
}
impl<Unit> Distance<Unit> {
fn new(value: f64) -> Self {
Distance { value, _unit: PhantomData }
}
fn value(&self) -> f64 { self.value }
}
impl Distance<Meters> {
fn to_feet(self) -> Distance<Feet> {
Distance::new(self.value * 3.28084)
}
}
fn main() {
let d_m: Distance<Meters> = Distance::new(100.0);
let d_f: Distance<Feet> = d_m.to_feet();
println!("{:.2} 英尺", d_f.value());
// 无法混合单位 — 类型系统会阻止此类操作
}Practices: Rust Engineering
实践篇:Rust工程化
Build Script ()
build.rsrust
// build.rs — runs before compilation
fn main() {
// Tell Cargo to rerun if C source changes
println!("cargo:rerun-if-changed=src/native/lib.c");
// Compile a C library
cc::Build::new()
.file("src/native/lib.c")
.compile("native");
// Emit link search path
println!("cargo:rustc-link-search=native=/usr/local/lib");
println!("cargo:rustc-link-lib=ssl");
}Cross-Compilation
bash
undefined构建脚本()
build.rsrust
// build.rs — 在编译前执行
fn main() {
// 告诉Cargo如果C源文件发生变化则重新编译
println!("cargo:rerun-if-changed=src/native/lib.c");
// 编译C库
cc::Build::new()
.file("src/native/lib.c")
.compile("native");
// 输出链接搜索路径
println!("cargo:rustc-link-search=native=/usr/local/lib");
println!("cargo:rustc-link-lib=ssl");
}交叉编译
bash
undefinedAdd a target
添加目标平台
rustup target add aarch64-unknown-linux-gnu
rustup target add aarch64-unknown-linux-gnu
Build for that target
为该目标平台构建
cargo build --target aarch64-unknown-linux-gnu
cargo build --target aarch64-unknown-linux-gnu
In .cargo/config.toml:
在.cargo/config.toml中配置:
[target.aarch64-unknown-linux-gnu]
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
linker = "aarch64-linux-gnu-gcc"
**Running Miri for Undefined Behavior Detection**
```bash
**使用Miri检测未定义行为**
```bashInstall Miri
安装Miri
rustup component add miri
rustup component add miri
Run tests under Miri
在Miri下运行测试
cargo miri test
cargo miri test
Run a specific binary under Miri
在Miri下运行特定二进制文件
cargo miri run
---cargo miri run
---Adding Content to a Book
为书籍添加内容
SUMMARY.md Structure
SUMMARY.md结构
markdown
undefinedmarkdown
undefinedSummary
目录
- Introduction
- Chapter 1: Ownership
- Borrowing
- Lifetimes
- Chapter 2: Types
undefined- 简介
- 第1章:所有权
- 借用
- 生命周期
- 第2章:类型
undefinedMermaid Diagrams in Chapters
章节中的Mermaid图表
markdown
```mermaid
graph TD
A[Value Created] --> B{Ownership Transfer?}
B -->|Move| C[New Owner]
B -->|Borrow| D[Temporary Reference]
C --> E[Original Invalid]
D --> F[Original Still Valid]
```markdown
```mermaid
graph TD
A[创建值] --> B{是否转移所有权?}
B -->|移动| C[新所有者]
B -->|借用| D[临时引用]
C --> E[原所有者失效]
D --> F[原所有者仍有效]
```Rust Playground Links
Rust在线编程环境链接
markdown
You can run this example in the [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main()+%7B+println!(%22Hello%22)%3B+%7D).markdown
你可以在 [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main()+%7B+println!(%22Hello%22)%3B+%7D) 中运行此示例。xtask Automation
xtask自动化
The pattern lets you write build scripts in Rust instead of shell:
xtaskrust
// xtask/src/main.rs — simplified pattern
use std::process::Command;
fn main() {
let task = std::env::args().nth(1).unwrap_or_default();
match task.as_str() {
"build" => build_all(),
"serve" => serve_all(),
"deploy" => deploy(),
"clean" => clean(),
_ => eprintln!("Unknown task: {task}"),
}
}
fn build_all() {
for book in &["c-cpp-book", "python-book", "async-book"] {
let status = Command::new("mdbook")
.args(["build", book])
.status()
.expect("mdbook not found");
assert!(status.success(), "Failed to build {book}");
}
}Run with: (configured in as an alias).
cargo xtask build.cargo/config.tomlxtask模式允许你使用Rust而不是shell编写构建脚本:
rust
// xtask/src/main.rs — 简化版示例
use std::process::Command;
fn main() {
let task = std::env::args().nth(1).unwrap_or_default();
match task.as_str() {
"build" => build_all(),
"serve" => serve_all(),
"deploy" => deploy(),
"clean" => clean(),
_ => eprintln!("未知任务: {task}"),
}
}
fn build_all() {
for book in &["c-cpp-book", "python-book", "async-book"] {
let status = Command::new("mdbook")
.args(["build", book])
.status()
.expect("未找到mdbook");
assert!(status.success(), "构建{book}失败");
}
}运行方式:(在中配置为别名)。
cargo xtask build.cargo/config.tomlCI/CD — GitHub Pages Deployment
CI/CD — GitHub Pages部署
yaml
undefinedyaml
undefined.github/workflows/pages.yml
.github/workflows/pages.yml
name: Deploy to GitHub Pages
on:
push:
branches: [master]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo install mdbook mdbook-mermaid
- run: cargo xtask deploy
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
---name: 部署到GitHub Pages
on:
push:
branches: [master]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo install mdbook mdbook-mermaid
- run: cargo xtask deploy
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
---Troubleshooting
故障排除
mdbook
command not found
mdbookmdbook
命令未找到
mdbookbash
cargo install mdbook mdbook-mermaidbash
cargo install mdbook mdbook-mermaidEnsure ~/.cargo/bin is in your PATH
确保~/.cargo/bin在你的PATH中
export PATH="$HOME/.cargo/bin:$PATH"
undefinedexport PATH="$HOME/.cargo/bin:$PATH"
undefinedMermaid diagrams not rendering
Mermaid图表无法渲染
bash
undefinedbash
undefinedEnsure preprocessor is installed
确保预处理器已安装
cargo install mdbook-mermaid
cargo install mdbook-mermaid
Verify book.toml has:
验证book.toml中包含以下配置:
[preprocessor.mermaid]
[preprocessor.mermaid]
command = "mdbook-mermaid"
command = "mdbook-mermaid"
undefinedundefinedPort already in use
端口已被占用
bash
undefinedbash
undefinedSpecify a different port
指定其他端口
mdbook serve --port 3001
undefinedmdbook serve --port 3001
undefinedBuild fails on specific book
某本书籍构建失败
bash
cd <book-name>
mdbook build 2>&1 # See full error outputbash
cd <书籍名称>
mdbook build 2>&1 # 查看完整错误输出Miri test failures
Miri测试失败
bash
undefinedbash
undefinedUpdate Miri to latest nightly
将Miri更新到最新的nightly版本
rustup update nightly
rustup component add miri --toolchain nightly
cargo +nightly miri test
undefinedrustup update nightly
rustup component add miri --toolchain nightly
cargo +nightly miri test
undefinedCross-compilation linker errors
交叉编译链接错误
bash
undefinedbash
undefinedInstall cross (Docker-based cross compilation)
安装cross(基于Docker的交叉编译工具)
cargo install cross
cross build --target aarch64-unknown-linux-gnu
---cargo install cross
cross build --target aarch64-unknown-linux-gnu
---Reading Path Recommendations
阅读路径推荐
New to Rust, coming from Python:
→ →
python-bookasync-bookrust-patterns-bookComing from C/C++:
→ →
c-cpp-bookrust-patterns-booktype-driven-correctness-bookComing from C#/Java:
→ →
csharp-bookasync-bookengineering-bookAlready know Rust basics:
→ →
rust-patterns-booktype-driven-correctness-bookengineering-bookProduction Rust:
+ (cancellation safety chapters)
engineering-bookasync-bookRust新手,来自Python背景:
→ →
python-bookasync-bookrust-patterns-book来自C/C++背景:
→ →
c-cpp-bookrust-patterns-booktype-driven-correctness-book来自C#/Java背景:
→ →
csharp-bookasync-bookengineering-book已掌握Rust基础:
→ →
rust-patterns-booktype-driven-correctness-bookengineering-book生产环境Rust开发:
+ (取消安全章节)
engineering-bookasync-bookLicense
许可证
Dual-licensed under MIT and CC-BY-4.0. Code examples are MIT; prose and diagrams are CC-BY-4.0.
采用MIT和CC-BY-4.0双重许可。代码示例采用MIT许可;文字和图表采用CC-BY-4.0许可。