模块系统
学习目标
- 理解模块和可见性
- 掌握
use 引入
- 理解文件系统与模块的关系
- 掌握
pub 和 pub(crate) 等可见性控制
核心概念
模块定义
mod math {
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
pub fn subtract(a: i32, b: i32) -> i32 {
a - b
}
fn internal_helper() -> i32 {
42
}
pub mod advanced {
pub fn power(base: i32, exp: u32) -> i32 {
(0..exp).fold(1, |acc, _| acc * base)
}
}
}
fn main() {
println!("{}", math::add(1, 2));
println!("{}", math::advanced::power(2, 10));
}
可见性
mod outer {
pub mod inner {
pub fn public_fn() {}
fn private_fn() {}
pub(crate) fn crate_fn() {}
pub(super) fn parent_fn() {}
}
fn test() {
inner::public_fn();
inner::private_fn();
inner::crate_fn();
inner::parent_fn();
}
}
use 引入
mod shapes {
pub struct Circle {
pub radius: f64,
}
impl Circle {
pub fn new(radius: f64) -> Self {
Circle { radius }
}
pub fn area(&self) -> f64 {
std::f64::consts::PI * self.radius * self.radius
}
}
pub mod utils {
pub fn diameter(radius: f64) -> f64 {
radius * 2.0
}
}
}
use shapes::Circle;
use shapes::utils::diameter;
use shapes::{Circle, utils};
fn main() {
let c = Circle::new(5.0);
println!("直径: {}", diameter(c.radius));
println!("面积: {}", c.area());
}
文件系统模块
src/
├── main.rs // mod math; 声明
├── math/
│ ├── mod.rs // pub fn add() ...
│ ├── basic.rs // pub fn subtract() ...
│ └── advanced.rs // pub fn power() ...
mod math;
fn main() {
math::add(1, 2);
math::basic::subtract(2, 1);
}
pub mod basic;
pub mod advanced;
pub fn subtract(a: i32, b: i32) -> i32 { a - b }
重导出
mod internal {
pub mod utils {
pub fn helper() {}
}
}
pub use internal::utils::helper;
fn main() {
helper();
}
use as 重命名
use std::collections::HashMap as Map;
use std::io::Result as IoResult;
fn main() {
let mut map: Map<String, i32> = Map::new();
map.insert("key".to_string(), 42);
}
实践练习
练习 1:组织代码
mod database {
pub mod connection {
pub struct Connection {
pub url: String,
}
impl Connection {
pub fn new(url: &str) -> Self {
Connection { url: String::from(url) }
}
}
}
pub mod query {
pub fn select(table: &str) -> String {
format!("SELECT * FROM {}", table)
}
}
}
use database::connection::Connection;
use database::query::select;
fn main() {
let conn = Connection::new("postgres://localhost/db");
println!("连接: {}", conn.url);
println!("查询: {}", select("users"));
}
练习 2:库结构
mod mylib {
mod internal {
pub fn process(data: &str) -> String {
data.to_uppercase()
}
}
pub fn transform(input: &str) -> String {
internal::process(input)
}
pub struct Transformer {
prefix: String,
}
impl Transformer {
pub fn new(prefix: &str) -> Self {
Transformer { prefix: String::from(prefix) }
}
pub fn apply(&self, input: &str) -> String {
format!("{}: {}", self.prefix, internal::process(input))
}
}
}
fn main() {
println!("{}", mylib::transform("hello"));
let t = mylib::Transformer::new("Result");
println!("{}", t.apply("world"));
}
常见错误
1. 忘记 pub
mod mymod {
fn helper() {}
}
2. 路径错误
mod a {
mod b {
pub fn hello() {}
}
}
小结
| 概念 | 说明 |
|---|
mod | 声明/定义模块 |
pub | 公开可见性 |
pub(crate) | crate 内可见 |
pub(super) | 父模块可见 |
use | 引入路径 |
use ... as ... | 重命名 |
pub use | 重导出 |