学习笔记十八——Rust 封装
🧱 Rust 封装终极指南:结构体、模块、Trait、目录结构与模块引用
🧭 目录导航
- 什么是封装?Rust 的封装理念
- Rust 的封装工具总览
- 模块(mod)和访问控制(pub)详解
- 结构体和枚举:封装数据
impl
和self
:封装行为- Trait:行为的抽象封装与多态实现
- 目录结构设计与模块引用
- 实战案例:带 Trait 的完整封装模块系统
- 总结:Rust 的封装哲学
1️⃣ 什么是封装?Rust 是怎么理解封装的?
封装的本质是:
将数据与操作它的方法组织在一起,并对外隐藏实现细节,只暴露对外接口。
Rust 提供了现代化、静态安全的封装机制,它不像 Java 有 class,但功能上实现了同样甚至更强的封装能力。
2️⃣ Rust 的封装工具总览
工具 | 功能 | 举例 |
---|---|---|
struct / enum | 封装一组字段 | struct User { name, password } |
impl | 给数据添加方法 | impl User { fn login(&self) { ... } } |
mod + pub | 封装逻辑模块 + 控制访问 | mod user; , pub fn login() |
trait | 抽象行为、实现接口、多态封装 | trait Printable { fn print(&self); } |
3️⃣ 模块和 pub:控制访问边界
Rust 的模块系统是封装最重要的边界控制工具。
- 所有内容默认私有
- 用
pub
显式开放 - 模块和目录一一对应(
mod.rs
或新写法modname.rs
+ 子模块)
4️⃣ 结构体和枚举:封装数据
pub struct User {pub name: String,password: String, // 私有字段
}pub enum LoginStatus {Success,Failure(String),
}
struct
封装实体数据enum
封装状态、结果、多种可能性
5️⃣ impl 和 self:封装方法与行为
impl User {pub fn new(name: &str, pwd: &str) -> Self {Self {name: name.to_string(),password: pwd.to_string(),}}pub fn check_password(&self, input: &str) -> bool {self.password == input}
}
6️⃣ Trait:封装行为的抽象方式
✅ 什么是 Trait?
Trait(特征)类似于 Java 的接口(interface):
- 它定义了某种能力/行为的抽象
struct
或enum
可以实现多个 trait- 外部通过 trait 使用对象,无需关心具体类型
🧠 举个例子:定义一个能“打印”的 trait
pub trait Printable {fn print(&self);
}
实现 trait:
pub struct User {pub name: String,
}impl Printable for User {fn print(&self) {println!("User: {}", self.name);}
}
🛠 Trait 的用法和封装意义
- 隐藏内部结构,只暴露行为接口
- 支持多态:多个类型实现同一个 trait
- 实现解耦:代码依赖于 trait 而不是具体类型
✨ Trait 封装进模块
你可以将 trait 和实现都封装在模块里:
// user/traits.rs
pub trait Printable {fn print(&self);
}
// user/mod.rs
mod traits;
pub use traits::Printable;pub struct User {pub name: String,
}impl Printable for User {fn print(&self) {println!("User: {}", self.name);}
}
外部模块这样使用:
use user::{User, Printable};fn main() {let u = User { name: "Tom".to_string() };u.print(); // 调用 trait 方法
}
🧪 高级技巧:Trait 作为函数参数(多态)
fn show_info(item: &impl Printable) {item.print();
}
或更通用写法:
fn show_info<T: Printable>(item: &T) {item.print();
}
这样你就实现了“只看能力,不看具体类型”。
7️⃣ 模块系统与封装结构设计
项目结构举例(目录 + 封装 + trait):
src/
├── main.rs
├── user/
│ ├── mod.rs
│ ├── model.rs // 数据结构
│ ├── service.rs // 行为逻辑
│ └── traits.rs // trait 定义
├── order/
│ ├── mod.rs
│ └── db.rs
└── utils.rs
每个模块目录都包含一个 mod.rs
,作为该模块的根,里面:
pub mod model;
pub mod service;
pub mod traits;pub use traits::*;
pub use model::User;
然后在 main.rs
中:
mod user;use user::{User, Printable};fn main() {let user = User::new("Alice");user.print();
}
🧠 8️⃣ 封装案例总结:Trait + 模块 + impl 的组合拳
内容 | 用途 | 封装表现 |
---|---|---|
struct / enum | 数据载体 | 私有字段保护数据不被外部访问 |
impl | 方法实现 | 把行为挂在数据上 |
trait | 抽象接口 | 通过能力驱动调用,不关心类型 |
mod / pub | 模块组织 | 文件结构决定模块结构,pub 决定可访问性 |
目录结构 | 工程可维护性 | 按功能拆模块,模块拆 trait/model/service |
✅ 9️⃣ 最终总结:Rust 封装哲学一句话
“能看什么是你说了算,能做什么是 trait 决定的,内部怎么做是我的事。”
Rust 提供了非常强大且显式的封装能力,它将“数据安全、接口清晰、逻辑隔离”做到了极致。