
文章目录
- [第1章 Rust语言概述](#第1章 Rust语言概述)
-
- [1.1 Rust的诞生与发展](#1.1 Rust的诞生与发展)
-
- [1.1.1 历史背景与诞生契机](#1.1.1 历史背景与诞生契机)
- [1.1.2 Mozilla的介入与语言演进](#1.1.2 Mozilla的介入与语言演进)
- [1.1.3 后1.0时代的发展](#1.1.3 后1.0时代的发展)
- [1.1.4 Rust基金会的成立](#1.1.4 Rust基金会的成立)
- [1.1.5 社区驱动的治理模式](#1.1.5 社区驱动的治理模式)
- [1.2 Rust的核心特性与优势](#1.2 Rust的核心特性与优势)
-
- [1.2.1 内存安全:零成本抽象的革命](#1.2.1 内存安全:零成本抽象的革命)
- [1.2.2 fearless concurrency:安全并发的革命](#1.2.2 fearless concurrency:安全并发的革命)
- [1.2.3 零成本抽象:高性能的保证](#1.2.3 零成本抽象:高性能的保证)
- [1.2.4 丰富的类型系统与模式匹配](#1.2.4 丰富的类型系统与模式匹配)
- [1.2.5 trait系统:灵活的多态](#1.2.5 trait系统:灵活的多态)
- [1.3 Rust应用场景与成功案例](#1.3 Rust应用场景与成功案例)
- [1.4 开发环境搭建与配置](#1.4 开发环境搭建与配置)
-
- [1.4.1 Rust工具链安装](#1.4.1 Rust工具链安装)
- [1.4.2 开发环境配置](#1.4.2 开发环境配置)
- [1.4.3 项目结构与工作流](#1.4.3 项目结构与工作流)
- [1.4.4 开发工具链详解](#1.4.4 开发工具链详解)
- [1.4.5 持续集成配置](#1.4.5 持续集成配置)
-
- [GitHub Actions配置](#GitHub Actions配置)
- [1.4.6 高级开发技巧](#1.4.6 高级开发技巧)
第1章 Rust语言概述
1.1 Rust的诞生与发展
1.1.1 历史背景与诞生契机
在计算机科学的发展历程中,系统级编程语言长期以来被C和C++所主导。这两种语言以其卓越的性能和对硬件的直接控制能力,成为了操作系统、浏览器、数据库等关键基础设施的首选工具。然而,随着软件系统变得越来越复杂,C和C++在内存安全、并发安全方面的局限性也日益凸显。
根据美国国家标准与技术研究院(NIST)的统计,内存安全漏洞如缓冲区溢出、使用后释放、空指针解引用等,占据了所有软件安全漏洞的相当大比例。这些漏洞不仅导致了严重的安全问题,还给软件开发者和企业带来了巨大的维护成本。
正是在这样的背景下,2006年,当时在Mozilla工作的Graydon Hoare开始了一个个人项目,目标是创建一门既能提供C++级别性能和控制力,又能确保内存安全和并发安全的编程语言。这个项目最初被称为"rust-lang",后来简化为"Rust"。
Graydon Hoare在设计Rust时,借鉴了多种编程语言的优秀特性:
- 从C++继承了零成本抽象的设计理念
- 从Haskell获得了类型系统和模式匹配的灵感
- 从Cyclone语言学习了区域内存管理的思想
- 从Erlang和Go中汲取了并发编程的经验
1.1.2 Mozilla的介入与语言演进
2009年,Mozilla看到了Rust在解决浏览器安全问题和性能问题方面的潜力,决定正式赞助这个项目。Mozilla的介入为Rust带来了更多的开发资源和明确的应用场景------构建下一代浏览器引擎Servo。
在Mozilla的支持下,Rust语言开始了系统性的演进:
2010-2012年:语言探索期
- 2010年,Mozilla正式宣布Rust项目
- 语言设计经历了多次重大变革,包括类型系统、所有权模型的建立
- 2012年1月发布第一个alpha版本,开始吸引早期采用者
2013-2014年:稳定性准备期
- 2013年引入重要的"所有权"和"借用"概念
- 2014年发布0.9版本,语言特性趋于稳定
- 社区开始形成,生态系统初步建立
2015年:里程碑时刻
- 2015年5月15日,Rust 1.0正式发布
- 承诺向后兼容,为企业采用奠定基础
- 发布了稳定的标准库和包管理器Cargo
1.1.3 后1.0时代的发展
Rust 1.0的发布并不是终点,而是一个新的起点。Rust团队采用了独特的"火车模型"发布周期:
六周发布周期
- 每六周发布一个新的稳定版本
- 新特性首先在nightly版本中测试
- 通过beta版本进一步稳定
- 最终进入稳定版
版本化演进
Rust的重要特性通过版本化(edition)机制引入:
- 2015版:奠定基础
- 2018版:引入async/await、改进模块系统等
- 2021版:改进闭包捕获、默认特性等
这种发布策略既保证了稳定性,又允许语言持续进化。
1.1.4 Rust基金会的成立
2021年2月,Rust基金会正式成立,这标志着Rust进入了一个新的发展阶段。基金会的创始成员包括:
- AWS
- 华为
- 微软
- Mozilla
基金会的成立确保了Rust的可持续发展,避免了单一公司控制的风险。各成员公司承诺在五年内投入百万美元级别的资金,用于支持Rust核心团队的发展和项目维护。
1.1.5 社区驱动的治理模式
Rust的成功很大程度上归功于其独特的治理模式:
核心团队(Core Team)
负责项目的整体方向和协调各个子团队的工作。
领域团队(Domain Teams)
包括语言设计、编译器、库、文档等专业团队,每个团队负责特定领域的技术决策。
工作组(Working Groups)
针对特定任务成立的临时团队,如异步编程、嵌入式、WebAssembly等。
RFC流程
所有重大变更都需要通过RFC(Request for Comments)流程,确保决策的透明性和社区参与。
这种去中心化的治理结构使得Rust能够平衡创新与稳定,同时保持社区的活力。
1.2 Rust的核心特性与优势
1.2.1 内存安全:零成本抽象的革命
Rust最革命性的特性是其所有权系统,它在编译时而非运行时保证内存安全。这一机制基于三个核心规则:
所有权三原则
- 每个值都有一个所有者
- 同一时间只能有一个所有者
- 当所有者离开作用域时,值将被丢弃
让我们通过具体示例深入理解这些原则:
rust
fn ownership_basics() {
// 字符串字面量,存储在栈上
let stack_str = "hello";
// String类型,数据存储在堆上
let heap_string = String::from("hello");
// 所有权转移:heap_string的所有权移动到new_owner
let new_owner = heap_string;
// 以下代码将无法编译:heap_string不再拥有数据
// println!("{}", heap_string); // 编译错误!
// stack_str是Copy类型,不会移动所有权
let copy_stack = stack_str;
println!("{}", stack_str); // 正常编译:stack_str仍然有效
println!("{}", copy_stack); // 也有效
}
借用与引用机制
为了避免所有权的频繁转移,Rust引入了借用(borrowing)概念:
rust
fn borrowing_example() {
let s1 = String::from("hello");
// 不可变借用:允许多个只读引用
let len = calculate_length(&s1);
println!("'{}' 的长度是 {}", s1, len); // s1仍然可用
// 可变借用:同一时间只能有一个可变引用
let mut s2 = String::from("world");
modify_string(&mut s2);
println!("修改后的字符串: {}", s2);
// 借用规则验证
let mut data = String::from("data");
let ref1 = &data; // 不可变借用 OK
let ref2 = &data; // 另一个不可变借用 OK
// let mut_ref = &mut data; // 编译错误:不能同时存在可变和不可变借用
println!("{}, {}", ref1, ref2);
}
fn calculate_length(s: &String) -> usize {
s.len()
// 这里不需要返回所有权,因为只是借用
}
fn modify_string(s: &mut String) {
s.push_str("!");
}
生命周期注解
Rust通过生命周期注解确保引用的有效性:
rust
// 生命周期注解 'a 确保返回的引用有效
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn lifetime_example() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("较长的字符串是: {}", result);
// 以下代码演示生命周期的重要性
// let result2;
// {
// let string3 = String::from("短");
// result2 = longest(string1.as_str(), string3.as_str());
// } // string3 在这里离开作用域
// println!("结果: {}", result2); // 编译错误:result2 引用已失效的值
}
1.2.2 fearless concurrency:安全并发的革命
Rust的并发模型建立在所有权系统之上,能够在编译时防止数据竞争。
线程安全的消息传递
rust
use std::thread;
use std::sync::mpsc; // 多生产者,单消费者
use std::time::Duration;
fn message_passing_concurrency() {
let (tx, rx) = mpsc::channel();
let tx1 = mpsc::Sender::clone(&tx); // 克隆发送端
// 生产者线程1
thread::spawn(move || {
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("thread"),
];
for val in vals {
tx1.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
// 生产者线程2
thread::spawn(move || {
let vals = vec![
String::from("more"),
String::from("messages"),
String::from("for"),
String::from("you"),
];
for val in vals {
tx.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
// 在主线程中接收消息
for received in rx {
println!("收到: {}", received);
}
}
共享状态的并发安全
rust
use std::sync::{Arc, Mutex};
use std::thread;
fn shared_state_concurrency() {
// 使用Arc(原子引用计数)进行线程间共享
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());
}
无数据竞争的保证
Rust在编译时防止了以下常见的并发错误:
- 数据竞争:多个线程同时访问同一数据,至少有一个在写
- 竞态条件:操作的结果依赖于执行时序
- 死锁:虽然Rust不能完全防止,但通过所有权系统大大减少
1.2.3 零成本抽象:高性能的保证
Rust的"零成本抽象"哲学意味着高级语言特性不会带来运行时开销。
泛型的单态化
rust
// 泛型函数
fn generic_function<T: std::fmt::Display>(value: T) {
println!("值为: {}", value);
}
// 在编译时,Rust会为每种实际使用的类型生成专用版本
fn monomorphization_example() {
generic_function(42); // 生成 fn generic_function_i32(value: i32)
generic_function("hello"); // 生成 fn generic_function_str(value: &str)
generic_function(3.14); // 生成 fn generic_function_f64(value: f64)
}
迭代器的零成本优化
rust
fn iterator_performance() {
let numbers = vec![1, 2, 3, 4, 5];
// 高级的迭代器用法
let sum: i32 = numbers
.iter()
.map(|x| x * 2)
.filter(|x| x > &5)
.sum();
println!("结果: {}", sum);
// 编译后,这段代码与手写的循环效率相同
// 等效的手写代码:
let mut sum_manual = 0;
for i in &numbers {
let doubled = i * 2;
if doubled > 5 {
sum_manual += doubled;
}
}
}
1.2.4 丰富的类型系统与模式匹配
强大的枚举类型
rust
enum WebEvent {
// 单元变体
PageLoad,
PageUnload,
// 元组变体
KeyPress(char),
Paste(String),
// 结构体变体
Click { x: i64, y: i64 },
}
fn process_event(event: WebEvent) {
match event {
WebEvent::PageLoad => println!("页面加载"),
WebEvent::PageUnload => println!("页面卸载"),
WebEvent::KeyPress(c) => println!("按键: {}", c),
WebEvent::Paste(s) => println!("粘贴: {}", s),
WebEvent::Click { x, y } => println!("点击位置: ({}, {})", x, y),
}
}
Option和Result类型
rust
fn option_result_examples() {
// Option<T> 处理可能缺失的值
let some_number = Some(5);
let no_number: Option<i32> = None;
match some_number {
Some(n) => println!("有值: {}", n),
None => println!("没有值"),
}
// Result<T, E> 处理可能失败的操作
fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {
if denominator == 0.0 {
Err("除以零错误".to_string())
} else {
Ok(numerator / denominator)
}
}
match divide(10.0, 2.0) {
Ok(result) => println!("结果: {}", result),
Err(e) => println!("错误: {}", e),
}
// 使用 ? 操作符简化错误处理
fn calculate() -> Result<f64, String> {
let a = divide(10.0, 2.0)?;
let b = divide(a, 3.0)?;
Ok(b)
}
}
1.2.5 trait系统:灵活的多态
rust
// 定义trait
trait Drawable {
fn draw(&self);
fn area(&self) -> f64;
}
// 为结构体实现trait
struct Circle {
radius: f64,
}
impl Drawable for Circle {
fn draw(&self) {
println!("绘制圆形,半径: {}", self.radius);
}
fn area(&self) -> f64 {
std::f64::consts::PI * self.radius * self.radius
}
}
struct Rectangle {
width: f64,
height: f64,
}
impl Drawable for Rectangle {
fn draw(&self) {
println!("绘制矩形: {}x{}", self.width, self.height);
}
fn area(&self) -> f64 {
self.width * self.height
}
}
// 使用trait对象实现动态分发
fn draw_all(shapes: &Vec<Box<dyn Drawable>>) {
for shape in shapes {
shape.draw();
println!("面积: {:.2}", shape.area());
}
}
1.3 Rust应用场景与成功案例
1.3.1 系统编程与基础设施
操作系统开发
Rust的内存安全特性使其成为操作系统开发的理想选择。一些著名的项目包括:
Redox OS:一个用Rust编写的类Unix操作系统
rust
// 简化的系统调用示例
pub fn sys_write(fd: usize, buffer: &[u8]) -> Result<usize, SystemError> {
match fd {
STDOUT => {
// 安全的缓冲区访问
let output = core::str::from_utf8(buffer)
.map_err(|_| SystemError::InvalidArgument)?;
print!("{}", output);
Ok(buffer.len())
}
_ => Err(SystemError::BadFileDescriptor),
}
}
Google Fuchsia:Google的新操作系统,大量使用Rust编写核心组件
浏览器引擎
Servo:Mozilla的下一代浏览器引擎,展示了Rust在复杂系统中的应用
rust
// 简化的样式计算
fn compute_style(node: &Node, parent_style: Option<&ComputedValues>) -> ComputedValues {
let mut values = ComputedValues::default();
// 安全地处理CSS属性继承
if let Some(parent) = parent_style {
values.inherit_from(parent);
}
// 应用节点特定的样式
values.apply_node_styles(node);
values
}
1.3.2 Web开发与WebAssembly
服务器端开发
使用Rust构建高性能的Web服务:
Actix-web框架示例
rust
use actix_web::{web, App, HttpServer, Responder};
async fn hello() -> impl Responder {
"Hello, World!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(hello))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
WebAssembly应用
Rust是WebAssembly的一等公民,为前端开发带来新的可能性:
rust
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct ImageProcessor {
width: u32,
height: u32,
pixels: Vec<u8>,
}
#[wasm_bindgen]
impl ImageProcessor {
pub fn new(width: u32, height: u32) -> ImageProcessor {
let pixel_count = (width * height) as usize;
ImageProcessor {
width,
height,
pixels: vec![0; pixel_count * 4], // RGBA
}
}
pub fn apply_filter(&mut self) {
// 安全的像素处理,无边界检查开销
for pixel in self.pixels.chunks_exact_mut(4) {
// 简单的灰度滤镜
let gray = (pixel[0] as f32 * 0.299
+ pixel[1] as f32 * 0.587
+ pixel[2] as f32 * 0.114) as u8;
pixel[0] = gray;
pixel[1] = gray;
pixel[2] = gray;
}
}
}
1.3.3 区块链与分布式系统
智能合约开发
Solana区块链使用Rust作为主要开发语言:
rust
use solana_program::{
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
msg,
pubkey::Pubkey,
};
entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
msg!("智能合约执行开始");
// 安全的账户数据处理
if let Some(account) = accounts.get(0) {
if !account.is_writable {
msg!("错误:账户不可写");
return Err(ProgramError::InvalidAccountData);
}
// 处理业务逻辑
process_transfer(account, instruction_data)?;
}
msg!("执行成功");
Ok(())
}
分布式数据库
TiKV:一个分布式事务键值数据库,用Rust编写
rust
impl Storage for RocksEngine {
fn async_get(&self, ctx: Context, key: Key) -> Self::GetFuture {
Box::pin(async move {
// 异步的数据库操作
let value = self.inner.get(&key)?;
// 安全的错误处理
match value {
Some(v) => Ok(Some(v)),
None => Ok(None),
}
})
}
}
1.3.4 嵌入式与物联网
嵌入式开发
Rust的no_std模式使其适合资源受限的环境:
rust
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use panic_halt as _;
#[entry]
fn main() -> ! {
// 访问硬件寄存器 - 内存安全的方式
let peripherals = stm32::Peripherals::take().unwrap();
let gpioa = &peripherals.GPIOA;
let rcc = &peripherals.RCC;
// 启用GPIOA时钟
rcc.ahbenr.modify(|_, w| w.iopaen().set_bit());
// 配置PA5为输出模式
gpioa.moder.modify(|_, w| w.moder5().output());
loop {
// 设置PA5高电平
gpioa.bsrr.write(|w| w.bs5().set_bit());
delay(1000000);
// 设置PA5低电平
gpioa.bsrr.write(|w| w.br5().set_bit());
delay(1000000);
}
}
fn delay(count: u32) {
for _ in 0..count {
cortex_m::asm::nop();
}
}
1.3.5 命令行工具开发
Rust的性能和安全性使其成为开发命令行工具的绝佳选择:
ripgrep:比grep更快的搜索工具
rust
// 简化的搜索功能
fn search_file(path: &Path, pattern: &Regex) -> Result<Vec<Match>, io::Error> {
let content = fs::read_to_string(path)?;
let mut matches = Vec::new();
for (line_num, line) in content.lines().enumerate() {
if let Some(captures) = pattern.captures(line) {
matches.push(Match {
line_number: line_num + 1,
content: line.to_string(),
captures: captures.iter().collect(),
});
}
}
Ok(matches)
}
1.4 开发环境搭建与配置
1.4.1 Rust工具链安装
跨平台安装方法
使用rustup(推荐)
rustup是Rust的官方安装工具,支持所有主流平台:
bash
# Linux/macOS
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Windows
# 下载并运行 rustup-init.exe 从 https://rustup.rs/
平台特定安装
Ubuntu/Debian:
bash
sudo apt update
sudo apt install rustc cargo
macOS with Homebrew:
bash
brew install rustup
rustup-init
Windows with Chocolatey:
bash
choco install rust
安装后验证
bash
# 验证安装
rustc --version
cargo --version
rustup --version
# 检查工具链状态
rustup show
# 更新工具链
rustup update
1.4.2 开发环境配置
IDE配置
Visual Studio Code配置
安装必要的扩展:
bash
# 安装rust-analyzer扩展
code --install-extension rust-lang.rust-analyzer
# 其他有用的扩展
code --install-extension bungcip.better-toml
code --install-extension serayuzgur.crates
code --install-extension vadimcn.vscode-lldb
配置VS Code的settings.json:
json
{
"rust-analyzer.check.command": "clippy",
"rust-analyzer.checkOnSave": true,
"rust-analyzer.cargo.loadOutDirsFromCheck": true,
"rust-analyzer.procMacro.enable": true,
"editor.formatOnSave": true,
"rust-analyzer.updates.channel": "stable"
}
IntelliJ IDEA配置
安装Rust插件并配置:
- 启用
org.rust.cargo.features.settings.gutter - 配置标准库源码路径
- 启用宏展开支持
Cargo配置优化
创建或修改~/.cargo/config.toml:
toml
[build]
# 并行编译
jobs = 8
# 增量编译
incremental = true
# 链接时优化
[profile.release]
lto = true
codegen-units = 1
panic = 'abort'
# 国内用户可配置镜像源
[source.crates-io]
replace-with = 'tuna'
[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"
[net]
git-fetch-with-cli = true
1.4.3 项目结构与工作流
标准项目结构
bash
my_project/
├── Cargo.toml # 项目配置和依赖
├── Cargo.lock # 精确的依赖版本(自动生成)
├── .gitignore
├── src/
│ ├── main.rs # 二进制crate的入口
│ ├── lib.rs # 库crate的入口
│ ├── bin/ # 额外的二进制文件
│ │ └── helper.rs
│ └── utils/
│ └── mod.rs # 模块声明
├── tests/ # 集成测试
│ └── integration_test.rs
├── benches/ # 基准测试
│ └── benchmark.rs
└── examples/ # 示例代码
└── basic_usage.rs
Cargo.toml详解
toml
[package]
name = "my_project"
version = "0.1.0"
edition = "2021" # Rust版本
authors = ["Your Name <email@example.com>"]
description = "一个用Rust编写的示例项目"
license = "MIT OR Apache-2.0"
# 依赖配置
[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }
reqwest = "0.11"
# 开发依赖
[dev-dependencies]
assert_eq = "0.1.0"
# 构建依赖
[build-dependencies]
cc = "1.0"
# 工作区配置(对于大型项目)
[workspace]
members = ["crates/*"]
1.4.4 开发工具链详解
调试工具配置
LLDB调试配置
创建.vscode/launch.json:
json
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/target/debug/${workspaceFolderBasename}",
"args": [],
"cwd": "${workspaceFolder}",
"sourceLanguages": ["rust"],
"preLaunchTask": "cargo build"
}
]
}
GDB调试配置:
json
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/target/debug/my_project",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "cargo build"
}
性能分析工具
perf使用示例:
bash
# 安装perf
sudo apt install linux-tools-common linux-tools-generic
# 性能分析
cargo build --release
perf record ./target/release/my_project
perf report
flamegraph生成:
bash
cargo install flamegraph
cargo flamegraph --bin my_project
测试与质量保证
单元测试示例:
rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_function() {
assert_eq!(2 + 2, 4);
}
#[test]
#[should_panic(expected = "out of bounds")]
fn test_panic_condition() {
panic!("out of bounds");
}
#[test]
fn test_result() -> Result<(), String> {
if 2 + 2 == 4 {
Ok(())
} else {
Err(String::from("数学出问题了!"))
}
}
}
基准测试:
rust
#![feature(test)]
extern crate test;
use test::Bencher;
#[bench]
fn bench_vector_creation(b: &mut Bencher) {
b.iter(|| {
let v: Vec<i32> = (0..1000).collect();
v
});
}
1.4.5 持续集成配置
GitHub Actions配置
创建.github/workflows/ci.yml:
yaml
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
components: clippy, rustfmt
- name: Check formatting
run: cargo fmt -- --check
- name: Clippy check
run: cargo clippy -- -D warnings
- name: Run tests
run: cargo test
- name: Build release
run: cargo build --release
coverage:
name: Code coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install cargo-tarpaulin
run: cargo install cargo-tarpaulin
- name: Generate coverage
run: cargo tarpaulin --verbose --workspace --out Lcov
- name: Upload to codecov
uses: codecov/codecov-action@v1
with:
file: lcov.info
1.4.6 高级开发技巧
条件编译
rust
// 平台特定代码
#[cfg(target_os = "linux")]
fn get_linux_info() -> String {
"运行在Linux上".to_string()
}
#[cfg(target_os = "windows")]
fn get_windows_info() -> String {
"运行在Windows上".to_string()
}
// 特性标志
#[cfg(feature = "advanced")]
mod advanced_features {
pub fn complex_algorithm() {
// 高级功能实现
}
}
// 测试专用代码
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_feature() {
// 测试代码
}
}
构建脚本
创建build.rs文件:
rust
fn main() {
// 设置环境变量
println!("cargo:rerun-if-changed=src/config.h");
// 链接系统库
println!("cargo:rustc-link-lib=dylib=ssl");
// 条件编译
if cfg!(target_os = "linux") {
println!("cargo:rustc-cfg=unix");
}
// 生成代码
let out_dir = std::env::var("OUT_DIR").unwrap();
let dest_path = std::path::Path::new(&out_dir).join("generated.rs");
std::fs::write(&dest_path, "pub const MESSAGE: &str = \"Hello from build script!\";").unwrap();
}
通过本章的全面学习,你已经深入了解了Rust语言的背景、特性、应用场景,并建立了完整的开发环境。从下一章开始,我们将动手编写第一个Rust程序,开启Rust编程的实践之旅。