Rust 库开发全面指南

发布于:2025-08-12 ⋅ 阅读:(18) ⋅ 点赞:(0)

Rust 库开发全面指南

在 Rust 中开发库(lib)是创建可重用代码的核心方式。下面我将详细介绍如何创建、开发和发布 Rust 库。

创建库项目

cargo new --lib mylib
cd mylib

项目结构:

mylib/
├── Cargo.toml
└── src/
    └── lib.rs

核心开发流程

1. 定义公共接口 (src/lib.rs)

//! 这是一个数学计算库
//! 
//! 提供各种数学计算功能

/// 计算两个数的和
/// 
/// # 示例
/// ```
/// use mylib::add;
/// 
/// assert_eq!(add(2, 3), 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

/// 计算阶乘
pub fn factorial(n: u64) -> u64 {
    (1..=n).product()
}

/// 自定义错误类型
#[derive(Debug)]
pub enum MathError {
    DivisionByZero,
    NegativeNumber,
}

/// 安全除法
pub fn safe_divide(a: f64, b: f64) -> Result<f64, MathError> {
    if b == 0.0 {
        Err(MathError::DivisionByZero)
    } else {
        Ok(a / b)
    }
}

2. 添加模块化结构

创建新文件 src/math.rs

/// 高级数学运算
pub mod advanced {
    /// 计算斐波那契数列
    pub fn fibonacci(n: u32) -> u64 {
        match n {
            0 => 0,
            1 => 1,
            _ => fibonacci(n - 1) + fibonacci(n - 2),
        }
    }
}

src/lib.rs 中引入:

pub mod math;

3. 添加单元测试

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(add(2, 2), 4);
    }

    #[test]
    fn test_factorial() {
        assert_eq!(factorial(5), 120);
    }

    #[test]
    fn test_safe_divide() {
        assert!(safe_divide(10.0, 0.0).is_err());
        assert_eq!(safe_divide(10.0, 2.0), Ok(5.0));
    }
}

4. 添加集成测试

创建 tests/integration_test.rs

use mylib::{add, math::advanced::fibonacci};

#[test]
fn test_add_integration() {
    assert_eq!(add(10, 20), 30);
}

#[test]
fn test_fibonacci() {
    assert_eq!(fibonacci(10), 55);
}

高级功能开发

1. 自定义类型

// src/geometry.rs
#[derive(Debug, PartialEq, Clone)]
pub struct Point {
    pub x: f64,
    pub y: f64,
}

impl Point {
    pub fn new(x: f64, y: f64) -> Self {
        Point { x, y }
    }
    
    pub fn distance(&self, other: &Point) -> f64 {
        ((self.x - other.x).powi(2) + (self.y - other.y).powi(2)).sqrt()
    }
}

2. 特征(Trait)系统

// src/shapes.rs
pub trait Area {
    fn area(&self) -> f64;
}

pub struct Circle {
    pub radius: f64,
}

impl Area for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius.powi(2)
    }
}

3. 宏开发

// src/macros.rs
#[macro_export]
macro_rules! vec2d {
    ($($x:expr),*) => {{
        let mut temp_vec = Vec::new();
        $(temp_vec.push($x);)*
        temp_vec
    }};
}

配置 Cargo.toml

[package]
name = "mylib"
version = "0.1.0"
edition = "2021"
authors = ["Your Name <your.email@example.com>"]
description = "A comprehensive math and geometry library"
license = "MIT OR Apache-2.0"
repository = "https://github.com/yourusername/mylib"
documentation = "https://docs.rs/mylib"

# 更多元数据
[package.metadata.docs.rs]
all-features = true

# 依赖管理
[dependencies]
serde = { version = "1.0", features = ["derive"], optional = true }
rand = "0.8"

# 可选特性
[features]
default = ["serde"]
geometry = []  # 启用几何功能
advanced = ["geometry"] # 启用高级功能

# 开发依赖
[dev-dependencies]
approx = "0.5" # 用于浮点数比较

文档系统

1. 编写文档注释

/// 计算两点之间的距离
///
/// # 示例
/// ```
/// use mylib::geometry::Point;
///
/// let p1 = Point::new(0.0, 0.0);
/// let p2 = Point::new(3.0, 4.0);
/// assert_eq!(p1.distance(&p2), 5.0);
/// ```
pub fn distance(&self, other: &Point) -> f64 {
    // ...
}

2. 生成文档

cargo doc --open

测试与基准测试

1. 单元测试

#[test]
fn test_point_distance() {
    let p1 = Point::new(0.0, 0.0);
    let p2 = Point::new(3.0, 4.0);
    assert_relative_eq!(p1.distance(&p2), 5.0, epsilon = 1e-10);
}

2. 集成测试

创建 tests/geometry_test.rs

use mylib::geometry::Point;

#[test]
fn test_point_creation() {
    let p = Point::new(1.0, 2.0);
    assert_eq!(p.x, 1.0);
    assert_eq!(p.y, 2.0);
}

3. 基准测试

// benches/benchmarks.rs
#![feature(test)]
extern crate test;
use test::Bencher;

#[bench]
fn bench_factorial(b: &mut Bencher) {
    b.iter(|| factorial(20));
}

运行基准测试:

cargo bench

发布到 crates.io

1. 准备发布

cargo login <your-api-token>
cargo publish --dry-run

2. 检查包

cargo package

3. 发布

cargo publish

高级主题

1. FFI 接口 (C API)

// src/ffi.rs
use std::os::raw::c_int;

#[no_mangle]
pub extern "C" fn rust_add(a: c_int, b: c_int) -> c_int {
    a + b
}

2. 条件编译

#[cfg(target_os = "linux")]
fn platform_specific() {
    println!("Running on Linux!");
}

#[cfg(feature = "serde")]
impl Serialize for Point {
    // ...
}

3. 错误处理最佳实践

use thiserror::Error;

#[derive(Error, Debug)]
pub enum GeometryError {
    #[error("invalid point coordinates: ({0}, {1})")]
    InvalidPoint(f64, f64),
    #[error("points are coincident")]
    CoincidentPoints,
}

pub fn calculate_slope(p1: &Point, p2: &Point) -> Result<f64, GeometryError> {
    if p1 == p2 {
        return Err(GeometryError::CoincidentPoints);
    }
    Ok((p2.y - p1.y) / (p2.x - p1.x))
}

最佳实践

  1. 模块化设计

    mylib/
    ├── src/
    │   ├── lib.rs
    │   ├── math.rs
    │   ├── geometry.rs
    │   ├── shapes.rs
    │   └── ffi.rs
    
  2. 文档驱动开发

    • 为所有公共项编写文档
    • 包含使用示例
  3. 全面的测试

    • 单元测试覆盖所有函数
    • 集成测试验证模块交互
    • 基准测试关键路径
  4. 版本管理

    • 遵循语义化版本控制 (SemVer)
    • 使用 cargo semver-checks 验证兼容性
  5. 持续集成

    # .github/workflows/ci.yml
    name: CI
    
    on: [push, pull_request]
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v2
        - name: Build
          run: cargo build --all-features
        - name: Test
          run: cargo test --all-features
        - name: Check
          run: cargo check
        - name: Clippy
          run: cargo clippy --all-targets --all-features -- -D warnings
        - name: Format
          run: cargo fmt -- --check
    

性能优化技巧

  1. 使用内联

    #[inline(always)]
    pub fn fast_add(a: i32, b: i32) -> i32 {
        a + b
    }
    
  2. 避免不必要的拷贝

    pub fn process_points(points: &[Point]) {
        // 使用引用而不是所有权
    }
    
  3. 利用迭代器

    pub fn sum_of_squares(numbers: &[i32]) -> i32 {
        numbers.iter().map(|x| x * x).sum()
    }
    
  4. 使用零成本抽象

    pub fn generic_add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
        a + b
    }
    

通过遵循这些实践,您可以创建高质量、可维护且高性能的 Rust 库,为 Rust 生态系统做出贡献。


网站公告

今日签到

点亮在社区的每一天
去签到