库 crate 与 workspace
你会学到什么
- 一个 package 可以同时包含库(
lib.rs)和二进制(main.rs)。 - 库 crate 通过
pubAPI 对外提供可复用逻辑。 - workspace 把多个相关 crate 放在一个仓库里统一管理。
最小示例
// src/lib.rs —— 库,对外暴露 API
pub fn celsius_to_fahrenheit(c: f64) -> f64 {
c * 9.0 / 5.0 + 32.0
}
// src/main.rs —— 二进制,按 crate 名引用库
use rt_29_library::celsius_to_fahrenheit;
运行代码
cd examples
cargo run -p rt_29_library
cargo test -p rt_29_library
代码讲解
库 crate 的根是 lib.rs,里面 pub 的项就是公开 API;二进制 crate 的根是 main.rs。当二者在同一个 package 时,main.rs 用 crate 名引用库:
use rt_29_library::{celsius_to_fahrenheit, fahrenheit_to_celsius};
本教程的 examples/ 目录本身就是一个 workspace。根 Cargo.toml 用 [workspace] 列出所有成员,它们共享同一个 Cargo.lock 和 target/:
[workspace]
members = ["00_hello_world", "01_cargo_project", "..."]
[workspace.package]
version = "0.1.0"
edition = "2024"
成员用 version.workspace = true 继承公共配置,避免重复。
常见错误
在 workspace 成员里各写各的依赖版本,导致版本漂移。可以用 [workspace.dependencies] 统一声明,成员再用 dep.workspace = true 继承。
练习
- 把
29_library的转换函数补一个kelvin_to_celsius。 - 新建一个 crate 依赖
rt_29_library,在Cargo.toml里用path引用它。
小结
库 crate 提供可复用 API,二进制 crate 提供入口,workspace 让多个 crate 共享配置与构建产物。
下一步
工程化的下一步是测试与文档。下一章进入质量保障阶段。
完整示例代码
下面是 examples/29_library/ 的完整源码。无需 clone 仓库,直接在页面上阅读、复制、对照运行。
examples/29_library/src/main.rs
//! 二进制部分:通过 crate 名引用同包的库。
use rt_29_library::{celsius_to_fahrenheit, fahrenheit_to_celsius};
fn main() {
println!("0°C = {}°F", celsius_to_fahrenheit(0.0));
println!("212°F = {}°C", fahrenheit_to_celsius(212.0));
} examples/29_library/src/lib.rs
//! 一个最小库 crate:温度单位转换。
//!
//! 库 crate 通过 `lib.rs` 对外暴露 API,二进制或其他 crate 都能复用。
/// 摄氏度转华氏度。
pub fn celsius_to_fahrenheit(celsius: f64) -> f64 {
celsius * 9.0 / 5.0 + 32.0
}
/// 华氏度转摄氏度。
pub fn fahrenheit_to_celsius(fahrenheit: f64) -> f64 {
(fahrenheit - 32.0) * 5.0 / 9.0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn converts_to_fahrenheit() {
assert_eq!(celsius_to_fahrenheit(0.0), 32.0);
assert_eq!(celsius_to_fahrenheit(100.0), 212.0);
}
#[test]
fn round_trips() {
let back = fahrenheit_to_celsius(celsius_to_fahrenheit(37.0));
assert!((back - 37.0).abs() < 1e-9);
}
} examples/29_library/Cargo.toml
[package]
name = "rt_29_library"
version.workspace = true
edition.workspace = true
publish.workspace = true