跳转至

模块与包管理

模块与包管理

📚 章节概述

本章将介绍 Rust 的模块系统和包管理。模块系统帮助你组织代码,包管理器 Cargo 帮助你管理依赖和构建项目。

🎯 学习目标

  • 理解模块系统的概念
  • 学会定义和使用模块
  • 掌握 use 关键字的使用
  • 学会使用 Cargo 管理依赖
  • 理解工作空间的使用

📖 模块系统

1.1 定义模块

Rust
mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}
        fn seat_at_table() {}
    }

    mod serving {
        fn take_order() {}
        fn serve_order() {}
        fn take_payment() {}
    }
}

1.2 模块树

Text Only
crate
 └── front_of_house
     ├── hosting
     │   ├── add_to_waitlist
     │   └── seat_at_table
     └── serving
         ├── take_order
         ├── serve_order
         └── take_payment

1.3 使用模块

Rust
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // 绝对路径
    crate::front_of_house::hosting::add_to_waitlist();

    // 相对路径
    front_of_house::hosting::add_to_waitlist();
}

1.4 使用 use 引入路径

Rust
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}

1.5 使用 use 的惯用方式

Rust
// 好:引入结构体、枚举等的完整路径
use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    map.insert(1, 2);
}

// 好:引入函数时,引入其父模块而非函数本身
use std::io;
// 然后通过 io::stdin() 调用,而不是直接 use std::io::stdin

// 好:使用嵌套路径引入多个项
use std::io::{self, Write};

1.6 使用 as 提供别名

Rust
use std::fmt::Result;
use std::io::Result as IoResult;

fn function1() -> Result {
    Ok(())
}

fn function2() -> IoResult<()> {
    Ok(())
}

1.7 重新导出

Rust
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

// 使用 pub use 重新导出
pub use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}

1.8 使用嵌套路径

Rust
// 旧方式
use std::cmp::Ordering;
use std::io;

// 新方式
use std::{cmp::Ordering, io};

// 使用 self
use std::io::{self, Write};

1.9 使用 glob 运算符

Rust
use std::collections::*;

📦 包与 Crate

2.1 包和 Crate 的区别

  • 包(Package):用于构建、测试和共享 crate 的 Cargo 功能
  • Crate:模块树,产生一个库或可执行文件

2.2 创建包

Bash
cargo new my_project --lib

2.3 包的结构

Text Only
my_project/
├── Cargo.toml
├── src/
│   ├── lib.rs
│   ├── main.rs
│   └── bin/
│       └── extra_main.rs
└── tests/
    └── integration_test.rs

2.4 定义模块

src/lib.rs

Rust
mod front_of_house;

pub use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}

src/front_of_house.rs

Rust
pub mod hosting {
    pub fn add_to_waitlist() {}
}

src/front_of_house/hosting.rs

Rust
pub fn add_to_waitlist() {}

🛠️ Cargo

3.1 Cargo.toml

TOML
[package]
name = "my_project"
version = "0.1.0"
edition = "2024"
authors = ["Your Name <you@example.com>"]

[dependencies]
serde = "1.0"
rand = "0.8"

[dev-dependencies]
criterion = "0.4"

[profile.release]
opt-level = 3
lto = true

3.2 添加依赖

TOML
[dependencies]
serde = { version = "1.0", features = ["derive"] }
rand = "0.8"
tokio = { version = "1.0", features = ["full"] }

3.3 依赖版本

TOML
# 精确版本
serde = "1.0.100"

# 兼容更新(推荐)
serde = "1.0"

# 范围版本
serde = ">=1.0.0, <2.0.0"

# 使用 commit hash
my_crate = { git = "https://github.com/user/repo", rev = "abc123" }

# 使用本地路径
my_crate = { path = "../my_crate" }

3.4 常用 Cargo 命令

Bash
# 构建项目
cargo build

# 运行项目
cargo run

# 运行测试
cargo test

# 检查代码
cargo check

# 生成文档
cargo doc --open

# 发布构建
cargo build --release

# 更新依赖
cargo update

# 清理构建文件
cargo clean

# 格式化代码
cargo fmt

# 代码检查
cargo clippy

📚 工作空间

4.1 创建工作空间

Cargo.toml

TOML
[workspace]
members = [
    "adder",
    "add_one",
]

4.2 工作空间结构

Text Only
workspace/
├── Cargo.toml
├── adder/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
└── add_one/
    ├── Cargo.toml
    └── src/
        └── lib.rs

4.3 在工作空间中使用依赖

add_one/Cargo.toml

TOML
[package]
name = "add_one"
version = "0.1.0"
edition = "2024"

[dependencies]

adder/src/main.rs

Rust
use add_one;

fn main() {
    let result = add_one::add_one(5);
    println!("Result: {}", result);
}

📝 练习题

练习 1:模块组织

Rust
// TODO: 创建一个模块结构
// - math 模块
//   - basic 子模块(add, subtract)
//   - advanced 子模块(multiply, divide)
// - utils 模块
//   - string 子模块(reverse, uppercase)

// TODO: 在 main 函数中使用这些模块

fn main() {
    // TODO: 实现
}

练习 2:use 关键字

Rust
// TODO: 使用 use 简化以下代码
mod math {
    pub mod basic {
        pub fn add(a: i32, b: i32) -> i32 {
            a + b
        }
    }
}

fn main() {
    let result = math::basic::add(1, 2);
    println!("Result: {}", result);
}

练习 3:Cargo 依赖

TOML
# TODO: 添加以下依赖到 Cargo.toml
# - serde: 1.0,启用 derive 特性
# - rand: 0.8
# - tokio: 1.0,启用 full 特性

[package]
name = "my_project"
version = "0.1.0"
edition = "2024"

[dependencies]
# TODO: 添加依赖

练习 4:工作空间

TOML
# TODO: 创建一个工作空间配置
# 包含两个成员:core 和 cli

[workspace]
members = [
    # TODO: 添加成员
]

💡 最佳实践

1. 模块组织

Rust
// 好:按功能组织模块
mod auth;
mod database;
mod api;
mod utils;

// 避免:按类型组织模块
mod models;
mod controllers;
mod views;

2. 使用 pub use 重新导出

Rust
// 好
pub use self::error::{Error, Result};

mod error {
    pub struct Error;
    pub type Result<T> = std::result::Result<T, Error>;
}

// 避免
mod error {
    pub struct Error;
    pub type Result<T> = std::result::Result<T, Error>;
}

3. 指定依赖版本

TOML
# 好
serde = "1.0"

# 避免
serde = "*"

4. 使用工作空间

TOML
# 好:相关项目使用工作空间
[workspace]
members = [
    "core",
    "cli",
    "server",
]

# 避免:独立项目不使用工作空间

⚠️ 常见错误

1. 模块可见性

Rust
// 错误:私有模块
mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}
    }
}

fn main() {
    front_of_house::hosting::add_to_waitlist(); // 编译错误
}

// 正确:使用 pub
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

2. use 路径

Rust
// 错误:use 引入函数
use std::collections::HashMap::new;

fn main() {
    new();
}

// 正确:use 引入模块
use std::collections::HashMap;

fn main() {
    HashMap::new();
}

3. 依赖版本冲突

TOML
# 错误:版本冲突
[dependencies]
crate1 = "0.1"
crate2 = { version = "0.2", features = ["crate1"] }

# 正确:使用兼容版本
[dependencies]
crate1 = "0.1"
crate2 = { version = "0.2", features = ["crate1_01"] }

📚 扩展阅读

🎯 本章小结

本章介绍了 Rust 的模块系统和包管理:

  • ✅ 理解模块系统的概念
  • ✅ 学会定义和使用模块
  • ✅ 掌握 use 关键字的使用
  • ✅ 学会使用 Cargo 管理依赖
  • ✅ 理解工作空间的使用

下一章: 我们将学习 Rust 的并发编程,包括线程、通道、消息传递和共享状态。