rust中的模块系统

rustcrate
创建时间: 2024-08-14 22:22:15修改时间: 2024-08-14 22:36:00

模块系统

模块系统存在的原因是代码量随着项目的增加而增加。日益庞大的系统就会有日益庞大的代码,这个时候组织项目的代码显得尤为重要。比如前端的工程化就是解决这个问题的,不得不说在当年前端能想到工程化的都是大佬哇。

各种语言的模块化

javascript中的模块化

这个是在javascript中到的导出的语法,在javascript中使用export,或者default export。来实现导入导出(这里不讨论node环境下的语法)

export function show() { console.log("模块化") }

导入语法

import {show} from './show.js'

javascript中的导入语法很简单,直接引入js文件即可,特别方便。

go 语言中的模块化

go语言的导出就是变量或函数名首字母大写即可,并不需要“./”,在当前项目中的子集文件夹就是一个package.只需要import一个package就可以使用这个包下的所有首字母大写的变量或函数了,下面是go语言导入的语法

import "project/packagename" // 项目名称/包名

可见在go和javascript中,他们的导入导出语法都设置得极其简单,上手就能用。

rust中的模块化

rust中的模块化的概念比较多,比较复杂。下面为用rust圣经的这本书里写的copy过来

  • 包(Packages):Cargo 的一个功能,它允许你构建、测试和分享 crate。
  • Crates :一个模块的树形结构,它形成了库或二进制项目。
  • 模块(Modules)和 use:允许你控制作用域和路径的私有性。
  • 路径(path):一个命名例如结构体、函数或模块等项的方式。

我的理解

  • 包(package):这个包应该就是指一个项目
  • Crates: 这个应该就是指模块的树型结构,比如linux里的/,这个crates就是指/
  • 模块(Modules):这个就是指使用mod关键字来标识一个模块
  • 路径(path):这个路径并不是javascript那样的路径,而是package::crates::mod这样子的路径

开始创建一个模块

首先,得在main.rs中声明模块,如下所示

pub mod say; fn main() { }

添加了这个模块声明后rust的编译器会自动寻找main.rs同级目录下的say文件,当然也可以是文件夹,但是前提是文件夹中必须存在mod.rs, 如下所示

// 这是同级目录下的say文件的用法 studySay ├── Cargo.lock ├── Cargo.toml └── src ├── say │ └── hello.rs ├── say.rs └── main.rs // 这是文件夹的用法 studySay ├── Cargo.lock ├── Cargo.toml └── src ├── say │ └── hello.rs │ └── mod.rs └── main.rs

rust提供了两种方式来声明子模块(当然有第三种方式,但是这里不做讨论。因为第三种方式是内联方式,懂的都懂哈哈哈~o~)

下面是代码的实现

方式一:使用根目录文件

// main.rs pub mod say; // 此处声明了say模块,rust编译器就会查找同级目录下的say.rs文件或者同级下的say文件夹 fn main() {}
// say.rs pub mod hello; // 此处是声明子模块
// say/hello.rs // 创建一个say_hello模块 pub mod say_hello { // 模块里的一个方法 pub fn say_hello_world() { println!("say hello world") } }

方式二: 使用mod.rs文件

// main.rs pub mod say; // 此处声明了say模块,rust编译器就会查找同级目录下的say.rs文件或者同级下的say文件夹 fn main() {}
// say/mod.rs pub mod hello; // 此处是声明子模块
// say/hello.rs // 创建一个say_hello模块 pub mod say_hello { // 模块里的一个方法 pub fn say_hello_world() { println!("say hello world") } }

可以看出上面的两种方式的唯一区别就是在say.rs和say/mod.rs的文件名不一样,至于为什么rust中存在这两种方式应该是考虑到了兼容性问题,这是rust圣经中的原话: "

另一种文件路径
目前为止我们介绍了 Rust 编译器所最常用的文件路径;不过一种更老的文件路径也仍然是支持的。

对于声明于 crate 根的 front_of_house 模块,编译器会在如下位置查找模块代码:

    src/front_of_house.rs(我们所介绍的)
    src/front_of_house/mod.rs(老风格,不过仍然支持)

对于 front_of_house 的子模块 hosting,编译器会在如下位置查找模块代码:

    src/front_of_house/hosting.rs(我们所介绍的)
    src/front_of_house/hosting/mod.rs(老风格,不过仍然支持)

如果你对同一模块同时使用这两种路径风格,会得到一个编译错误。在同一项目中的不同模块混用不同的路径风格是允许的,不过这会使他人感到疑惑。

使用 mod.rs 这一文件名的风格的主要缺点是会导致项目中出现很多 mod.rs 文件,当你在编辑器中同时打开它们时会感到疑惑。

",所以按照官方的说明,使用say.rs的这种方式更加现代化。

使用mod

上面说明里如何声明mod,现在我们需要使用mod。 代码如下

// 找到say模块中的hello模块中的say_hello模块 use say::hello::say_hello; // 使用模块 pub mod say; // 声明模块 fn main() { // 使用say_hello模块下的say_hello_world方法 say_hello::say_hello_world(); }

上述就是一直困扰为很久的rust模块的问题,真的和c/cpp那样要一个个模块声明,感觉真的好麻烦啊。

评论