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

rust- 定义模块以控制作用域和隐私

定义模块以控制作用域和隐私

本节中,我们将讨论模块及模块系统的其他部分,即路径(允许你为项命名);use 关键字(将路径引入作用域);以及 pub 关键字(使项公开)。我们还会讨论 as 关键字、外部包和通配符操作符。

模块速查表

在详细介绍模块和路径之前,这里提供一个关于编译器中模块、路径、use 和 pub 关键字如何工作的快速参考,以及大多数开发者如何组织代码。本章将通过示例逐条讲解这些规则,但这里是回顾模块工作原理的好地方。

  • 从 crate 根开始:
    编译 crate 时,编译器首先查看 crate 根文件(通常库 crate 是 src/lib.rs,二进制 crate 是 src/main.rs)中的代码进行编译。

  • 声明模块:
    在 crate 根文件中,你可以声明新模块;例如声明一个 “garden” 模块使用 mod garden; 。编译器会在以下位置寻找该模块的代码:

    • 内联,在用花括号替代 mod garden 后分号的位置内写代码块
    • 文件 src/garden.rs 中
    • 文件 src/garden/mod.rs 中
  • 声明子模块:
    在除根文件之外的任何文件中,都可以声明子模块。例如,可以在 src/garden.rs 中声明 mod vegetables; 。编译器会在父级同名目录下寻找子模块代码,具体位置包括:

    • 内联,在用花括号替代 mod vegetables 后分号的位置内写代码块
    • 文件 src/garden/vegetables.rs 中
    • 文件 src/garden/vegetables/mod.rs 中
  • 访问模块中的代码路径:
    一旦某个模块成为你的 crate 的一部分,只要隐私规则允许,就可以从同一crate中的任意位置通过该代码的路径引用它。例如,garden::vegetables 模块里的 Asparagus 类型可通过 crate::garden::vegetables::Asparagus 来访问。

  • 私有与公共:
    默认情况下,一个模组内部的代码对其父模组是私有的。若想让一个模组变成公共,则需使用 pub mod 而非 mod 声明。同样,要让公共模组内的项也变成公有,需要在它们前面加上 pub 修饰符。

  • use 关键字:
    在某个作用域内,use 用于创建项目快捷方式,以减少长路径重复。在任何能引用到 crate::garden::vegetables::Asparagus 的作用域里,可以用 use crate::garden::vegetables::Asparagus; 创建快捷方式,此后只需写 Asparagus 即可使用该类型。

下面举例说明以上规则,我们创建了一个名为 backyard 的二进制crate,其目录结构如下:

backyard
├── Cargo.lock
├── Cargo.toml
└── src├── garden│   └── vegetables.rs├── garden.rs└── main.rs

此处crate根文件是src/main.rs,其内容如下:

Filename: src/main.rs

use crate::garden::vegetables::Asparagus;pub mod garden;fn main() {let plant = Asparagus {};println!("I'm growing {plant:?}!");
}

pub mod garden; 告诉编译器包含位于src/garden.rs中的代码,该文件内容为:

Filename: src/garden.rs

pub mod vegetables;

这里 pub mod vegetables; 表示同时包含了src/garden/vegetables.rs中的内容,该文件内容为:

#[derive(Debug)]
pub struct Asparagus {}

接下来我们深入了解这些规则并演示其实践!

将相关代码归类到各个模组中

Modules 可以帮助我们组织crate内部的代码,提高可读性和复用性。同时,它们还能控制项目成员间隐私,因为默认情况下,一个module内部定义的是私有项,不对外暴露。这些“私有”元素仅作为实现细节存在,不供外部调用。如果需要,也可以选择把整个module或其中特定元素设为public,从而允许外部依赖调用它们。

举例来说,我们来写一个餐厅功能库crate,仅定义函数签名不实现具体逻辑,以便专注于如何组织这段程序,而不是餐厅业务本身。

餐饮行业常把餐厅划分成“前台”和“后台”。前台指客户所在区域,包括迎宾安排座位、服务员点单付款以及调酒师调饮料等环节;后台则是厨师做菜、洗碗工清洁及管理人员处理行政事务之地。

为了按此思路构建我们的crate,可采用嵌套modules来分类函数。在终端运行 cargo new restaurant --lib 新建库,然后编辑src/lib.rs,将7-1列表所示源码输入进去,实现前台(front_of_house)部分功能签名:

Filename: src/lib.rs

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() {}}
}

7-1列表:“front_of_house” module 包含两个子module,每个都含若干函数

我们用mod关键词加名称定义module(此处即front_of_house),然后把主体放入花括号{}内。在这个module里,还能继续嵌套其它modules,如hosting与serving。此外modules还能容纳structs, enums, constants, traits等各种定义,本例展示的是functions。

利用modules,我们能够聚合相关定义,并赋予其意义上的关联名称。这样程序员阅读时就能基于group定位目标,而不用遍历所有定义,更易找到关心部分;新增功能时也知道应往哪儿添加才能保持结构整齐。

此前提过,src/main.rs 与src/lib.r s被称作crateroots,是因为这两个源文件里的全部内容组成了顶层叫做crate名字空间(module)树状结构(root of the module tree)。

7-2列表显示了7-1列出的结构对应得module树形图:

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

7-2列表:“Listing 7–1”的Module树形图

这棵树展现了一些modules嵌套关系,比如hosting就是nest(嵌套) 在front_of_house里面。同时也体现出兄弟关系——hosting与serving都是front_of_house下平级兄弟节点。如果A module包含B module,则说B是A孩子节点(A parent)。注意整个tree由隐式root叫做crate起始。

这个module树很像电脑中文件系统目录树,非常贴切!正如filesystem里的目录用于整理存储,同理你借助modules整理你的code。而且跟directory里的files一样,你需要方法去定位自己的modules。

上面这段话太难理解,请你以图文形式展示。但是不要改变文章的意思。但你需要完整的返回文章内容

http://www.lryc.cn/news/601865.html

相关文章:

  • 握手未来,PostgreSQL认证专家
  • 【I】题目解析
  • Spring AI 学习笔记
  • 小架构step系列27:Hibernate提供的validator
  • 「mysql」Mac osx彻底删除mysql
  • Java面试宝典:MySQL性能优化
  • uart通信
  • JVM类加载机制全流程详解
  • 从MySQL的information_schema系统数据库中获取表的元数据信息
  • MySQL - 索引(B+树)
  • Cgroup 控制组学习(三)在容器中使用 CGroups
  • MySQL - 主从复制与读写分离
  • Cline与Cursor深度实战指南:AI编程助手的革命性应用
  • 基于CNN图像特征提取流程(简化版)
  • Linux实战:从零搭建基于LNMP+NFS+DNS的WordPress博客系统
  • Flink窗口:解锁流计算的秘密武器
  • QT---概览
  • 使用frp实现免费内网穿透
  • Triton Shared编译
  • 【前后端】node mock.js+json-server
  • LeetCode Hot 100 括号生成
  • 力扣热题100----------41.缺少的第一个正数
  • NodeJs接入腾讯云存储COS
  • PROFINET转CAN通讯协议转换速通汽车制造
  • 解析json异常, ObjectMapper注册的问题
  • 生成式召回-TIGER范式
  • BUG记录——Request接传Json数据中文乱码
  • C语言——————学习笔记(自己看)
  • Oracle 19C RU 19.28 升级和安装
  • Frontiers in Psychology投稿LaTeX(三)