当前位置: 首页 > news >正文

Rust 的“家族隐私”法则:深入理解 pub 与可见性

作为一名大学生,你可能已经写过一些 Rust 代码,用过 pub 关键字。但你是否曾困惑:为什么有些函数在模块外无法调用?为什么有些结构体字段无法直接访问?这背后其实是 Rust 精心设计的一套可见性规则,它就像一套“家族隐私法则”,用于管理代码的访问权限。

一、从一个简单的“家族”类比开始

想象一下,你的大学里有一个社团(Crate)。这个社团里有很多部门(Module),比如“技术部”、“宣传部”等。

  • Crate (社团):是你项目的最外层,一个独立的编译单元。可以是一个二进制程序(src/main.rs)或一个库(src/lib.rs)。

  • Module (部门):用于组织代码、控制可见性(隐私)的命名空间。

在这个社团里,每个部门(模块)都有自己的“家规”,规定了哪些家当(函数、结构体、变量等)是:

  1. 完全公开的:任何人都可以来看、来用。

  2. 部门内部使用的:只有本部门的成员才能使用。

  3. 对友邻部门开放的:只有社团内部的其他部门可以使用,外人不行。

Rust 的可见性系统,就是在帮我们定义这些“家规”。

二、核心关键字:pub 的不同修饰符

pub 关键字就是用来声明“这个东西是公开的”。但公开给谁?这里有不同的级别:

可见性级别关键字类比解释
私有(无,默认)部门内部的秘密文件,只有本部门的人能看。
完全公开pub社团的海报,贴在校内公告栏,校内校外的人都能看。
在父模块中可见pub(super)给上级领导(父部门)看的汇报材料。
在整个Crate内可见pub(crate)社团内部共享的文档,所有部门都能看,但不会发给校外的人。
在指定路径可见pub(in path::to::module)指定只给某个“友邻部门”看的资料。

默认情况(私有):在 Rust 中,所有项(函数、结构体、枚举、常量等)默认都是私有的。这体现了 Rust 的安全哲学:除非你明确允许,否则一切都是封闭的。

三、图示:一个代码“社团”的结构

让我们来看一个具体的代码例子和它的结构图。

// src/lib.rs - 我们的“社团”总部pub mod department_a { // 部门Apub fn public_function() { // 完全公开的函数println!("Anyone can call me!");}pub(crate) fn internal_docs() { // 社团内部使用的函数println!("For crate eyes only.");}fn private_function() { // 部门私有的函数println!("Top secret of department A!");}pub mod secret_team { // 部门A下的一个秘密小组use super::private_function; // 可以访问上级的私有项pub fn do_secret_work() {println!("Secret team is working...");private_function(); // 合法!小组可以调用部门的私有函数}}
}pub mod department_b { // 部门Buse crate::department_a;pub fn try_access() {department_a::public_function(); // 合法!完全公开department_a::internal_docs();   // 合法!同属一个crate// department_a::private_function(); // 错误!无法访问其他部门的私有项// department_a::secret_team::do_secret_work(); // 合法!因为do_secret_work是pub的}
}// 来自“校外”的访问(比如在 main.rs 中)
use my_crate::department_a;fn main() {department_a::public_function(); // 合法!// department_a::internal_docs(); // 错误!校外的人看不到内部文档
}

现在,我们用一张图来直观展示上面的访问关系:

text+--------------------------------------------------------------------+
|                        Crate: my_crate (社团)                      |
|                                                                    |
|  +---------------------------+    +---------------------------+   |
|  |   Module: department_a    |    |   Module: department_b    |   |
|  |                           |    |                           |   |
|  |  +---------------------+  |    |  +---------------------+  |   |
|  |  | pub fn public_fn    |<------|--| (可以访问)          |  |   |
|  |  | (对外完全公开)       |  |    |  |                     |  |   |
|  |  +---------------------+  |    |  +---------------------+  |   |
|  |                           |    |                           |   |
|  |  +---------------------+  |    |  +---------------------+  |   |
|  |  | pub(crate) internal |<-------|--| (可以访问)          |  |   |
|  |  | (仅社团内部可见)     |  |    |  |                     |  |   |
|  |  +---------------------+  |    |  +---------------------+  |   |
|  |                           |    |                           |   |
|  |  +---------------------+  |    |  +---------------------+  |   |
|  |  | fn private_fn       |  |    |  | (无法访问!)          |  |   |
|  |  | (部门A私有)         |  |    |  |                     |  |   |
|  |  +---------------------+  |    |  +---------------------+  |   |
|  |          ^                |    |                           |   |
|  |          | (super可以访问) |    +---------------------------+   |
|  |  +---------------------+  |                                    |
|  |  | mod secret_team     |  |                                    |
|  |  |                     |  |    +---------------------------+   |
|  |  | +-----------------+ |  |    |  External: src/main.rs    |   |
|  |  | | (可以调用       | |  |    |  (校外)                   |   |
|  |  | | private_fn)     | |  |    |                           |   |
|  |  | +-----------------+ |  |    |  +---------------------+  |   |
|  |  +---------------------+  |    |  | 只能访问 public_fn  |--|------+
|  +---------------------------+    |  | (无法访问internal!) |  |   |
|                                   |  +---------------------+  |   |
+--------------------------------------------------------------------+

图解说明:

  • 实线箭头:表示允许的访问。

  • 虚线箭头并带“叉”:表示被规则禁止的访问。

  • department_b 可以访问 department_a 的 public 和 pub(crate) 项,因为它们同属一个 Crate。

  • secret_team 可以访问其父模块 department_a 的私有项,这是 super 路径的威力。

  • 外部的 main.rs 只能访问被标记为 pub 的项,pub(crate) 的项对它来说是隐藏的。

四、结构体与枚举的可见性

可见性规则同样适用于复合类型,但有一点小变化。

1. 结构体(Struct)

结构体本身的可见性和其字段的可见性是分开的

pub mod department_a {// 这个结构体对外部是公开的pub struct OpenHouse {pub address: String, // 地址也是公开的pub(crate) internal_phone: String, // 内部电话只有crate内能访问secret_code: u32, // 密码是绝对私有的,外界甚至无法访问这个字段}impl OpenHouse {// 一个公共的构造函数,是创建OpenHouse的唯一方式pub fn new(addr: String, phone: String, code: u32) -> Self {OpenHouse {address: addr,internal_phone: phone,secret_code: code,}}// 一个公共的方法,可以间接读取私有字段pub fn check_code(&self, code: u32) -> bool {self.secret_code == code}}
}// 在外部使用
use my_crate::department_a::OpenHouse;fn main() {let house = OpenHouse::new("Rust Ave".to_string(), "123".to_string(), 42);println!("Address: {}", house.address); // 合法// println!("Phone: {}", house.internal_phone); // 错误!外部无法访问// println!("Code: {}", house.secret_code); // 错误!字段私有house.check_code(50); // 合法,通过公共接口与私有字段交互
}

要点:即使结构体是 pub 的,其字段也默认是私有的。这实现了封装,你可以精确控制哪些数据可以直接修改,哪些必须通过方法。

2. 枚举(Enum)

枚举的可见性规则更简单:如果枚举是 pub 的,那么它的所有变体也都是公开的

pub mod department_a {pub enum PublicEvent { // 公开的枚举OpenSeminar,       // 所有变体自动公开Workshop,          // 所有变体自动公开InternalMeeting,   // 所有变体自动公开}
}

这是因为枚举的变体是其类型的组成部分,将它们全部公开通常更有用。

五、为什么要这样设计?给大学生的启示

  1. 契约与安全:可见性规则在你(代码作者)和用户(其他程序员,包括未来的你)之间建立了一份清晰的“契约”。它明确指出了哪些功能是稳定的、可供外部使用的 API,哪些是可能变化的内部实现细节。这避免了用户误用内部接口,从而在你修改内部代码时,他们的代码不会崩溃。

  2. 高内聚,低耦合:鼓励你将相关的数据和行为封装在模块内。模块内部可以自由地修改和重构,只要不改变其公开的接口,就不会影响到外部代码。这是构建大型、可维护软件系统的基石。

  3. 清晰的抽象边界:通过强制使用 pub 来暴露接口,Rust 促使你思考:“这个函数/结构体真的需要被外界使用吗?” 这有助于设计出更清晰、更抽象的 API。

总结

可以把 Rust 的可见性系统想象成一个精密的权限管理系统:

  • 默认私有:保护你的代码,防止意外耦合。

  • pub:打开大门,完全公开。

  • pub(crate):一个非常实用的中间地带,用于创建crate 内部的 API,对外隐藏实现细节。

  • pub(super) 和 pub(in path):用于更精细的作用域控制,在复杂的模块树中非常有用。

http://www.dtcms.com/a/546617.html

相关文章:

  • dedecms招聘网站网站建设中的主要功能
  • 动易网站怎么进入后台宁波外贸网站制作
  • 怎么建立网站的流程网站建设 推广找山东博达
  • html做的网站图片横着摆放网站开发与设计英文文献
  • 宁波网站排名滨州做企业网站
  • 更新一下博客新样式
  • 电子元器件-接口电路篇:RS-232、RS485/422、I2C、SPI、USB、网口
  • 教育网站模块建设浙江seo外包费用
  • 网站建设公司的名字线上装修设计
  • 网站建设公司销售提成南昌seo哪家好
  • 怎么关注网站 在手机上冠县做网站哪里好
  • 建设食品网站网站建设定制开发服务
  • 深入解析 Rust 内部可变性模式:安全与灵活的完美平衡
  • 西安360免费做网站网校网站毕业设计的方案
  • haclon csv文件操作 及写入封装文件
  • HTML5+CSS3+JS小实例:拉链滑块控件
  • Context Engineering概述
  • wordpress配置多站点中山做网站排名
  • 广州做网站做得比较好如何创建网站主页
  • 三门峡专业做网站公司app手机软件开发
  • 在多线程中使用RequestScope的bean【最佳实践】
  • 百度商桥怎么嵌入网站公司网站建设内部调查
  • AOI在FPC制造领域的检测应用
  • 沧州网站建设优化公司seo排名快速优化
  • 杭州网站优化咨询西安软件开发培训机构
  • 南宁论坛建站模板东营建设信息网网
  • AI+若依框架(实战篇)-后转
  • 备案号被取消 没有重新备案网站会被关闭吗域名怎么查
  • 网站建设需要什么书沧州市快伟网络科技有限公司
  • 专业建设网站外包河北承德建设工程信息网站