我的编程空间,编程开发者的网络收藏夹
学习永远不晚

深入讲解下Rust模块使用方式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

深入讲解下Rust模块使用方式

前言

本文适用于刚开始学习rust的同学,用于帮助理解rust模块间是如何相互引用的。本文尽量用极少的代码来演示,即便之前没有了解过rust也可以混个眼熟。用的时候可以有个印象。

如果你之前没有了解过rust,只需要知道:Cargo-依赖管理工具,类似于npm,Cargo 使用文件放置约定,即文件名就是模块名。crate-集装箱,是一组功能的封装,类似于npm包。

本文探讨的场景是在项目中对代码进行不同程度的文件拆分和模块抽离时,往往需要在一个文件中引入另一个模块的部分代码,在javascript中,我们可以通过导入导出来使用其他模块的代码,这个过程我们只需要关心导入路径是否正确。

export const name= xx 
import lodash from './lodash'

而在rust中,模块不再通过文件路径的方式引入,而是通过cargo以及约定的模块声明方式来构建模块树,然后通过use关键字来使用。但是rust的文档在文件拆分和模块使用上做的示例不太详细,于是就参考一些发布的crate的组织方式进行了梳理。

模块声明&使用

假如我们想实现一个加法模块,并提供给其他地方使用。我们可以有如下三种组织方式

Cargo 使用文件放置约定,因此模块查找以class="lazy" data-src目录下的rs文件或者目录为准,并且只会查找一级,嵌套文件夹下的rs文件不可以直接被其他文件使用。

方法一:直接在根文件下声明 add.rs

我们可以通过在class="lazy" data-src下添加模块名同名的文件,cargo就可以识别到add模块。

├── Cargo.lock
├── Cargo.toml
├── class="lazy" data-src
│   ├── add.rs
│   ├── lib.rs

方法二:声明add文件夹,文件夹下包含 mod.rs

如果模块是文件夹,则必须有mod.rs文件。这类似于javascript的index.js。cargo仍然可以识别到这是add模块

├── Cargo.lock
├── Cargo.toml
├── class="lazy" data-src
│   ├── add
│   │   ├── mod.rs
│   ├── lib.rs

假设我们的代码内容如下,并位于文件add.rs 或者add/mod.rs内

pub fn add_fn(a: i32, b: i32) -> i32 {
    a + b
}

那么在lib.rs中我们可以通过如下方式调用我们的add模块

// 声明模块并引用模块内的函数
mod add;
pub use crate::add::add_fn;
pub fn test_lib() {
  add_fn(1,2);
}

方法三:add.rs和add文件夹同时存在

这种方式的目录结构看起来像下面这样

├── Cargo.lock
├── Cargo.toml
├── class="lazy" data-src
│   ├── add
│   │   └── add_m.rs
│   ├── add.rs // index.js
│   ├── lib.rs

add.rs负责入口模块的导入导出,add文件夹下则存放其余相关联的其他模块。这类似于javascript的index.js统一导出了多个其他模块。和上面不同的是这里 导入使用到了mod关键字来拆分模块;

文件内容看起来像下面这样

add.rs

pub mod add_m;
// 类似于 export * from './validate; export * from './helper'

add/add_m.rs

pub fn add_fn(a: i32, b: i32) -> i32 {
    a + b
}

lib.rs

mod add;
pub use crate::add::add_m::add_fn;
pub fn test_lib() {
  add_fn(1,2);
}

上述三种方式使用较多的应该是前两种,并且在大型项目内第二种更为合理,可以更好的组织文件。那么当一个模块文件夹下拆分多个模块文件时该怎调用相邻文件呢?

同模块相邻文件引用

我们调整目录结构如下

├── Cargo.lock
├── Cargo.toml
├── class="lazy" data-src
│   ├── add
│   │   ├── mod.rs
│   │   ├── print.rs
│   │   └── user.rs // user会调用print的方法
│   ├── lib.rs

在add模块下多了print和user。user会调用print的方法。

print.rs

pub mod my_print {
    pub fn print_hello() {
        println!( hello )
    }
}
// 这里的pub mod 可以简单理解为ts的declare module ,里面是module的可用属性
// declare module my_print {
//  export function print_hello(): string;
// }

user.rs

use super::print::my_print;
pub fn hello_user() {
    my_print::print_hello();
}
pub struct User {
    pub name: String,
}

同模块下的文件互相引用使用super关键字。

mod.rs

// mod.rs为入口文件, 下面用mod声明会先去同文件夹下查找同名文件,如果没有则看是否有满足条件   的同名文件夹
// 例如 add 文件夹下没有print.rs 则查找是否有print文件夹并且文件夹下有mod.rs。
mod print;
mod user;

// 因为是同一个模块文件夹下,并且在入口文件使用,所以这里应self
pub use self::user::hello_user;
pub use self::user::User;

pub mod add_fn {
    // use super::*; 如果有这行,则下面不用每次调用super
    pub fn add(a: i32, b: i32) -> i32 {
      // 注意这里super关键字,因为hello_user是在另一个模块声明的,模块间不能直接调用所以需要使用super来从模块根进行查找调用
        super::hello_user();

        let value = super::User {
            name: String::from( Rust ),
        };

        println!( user name {} , value.name);
        a + b
    }
}

pub fn test_out_ref() {
  // 这里不在需要super因为不在mod内定义
    hello_user();
}

不同模块引用

我们新增一个模块multip,返回两个数相乘的结果,目录结构如下

├── Cargo.lock
├── Cargo.toml
├── class="lazy" data-src
│   ├── add
│   │   ├── mod.rs
│   │   ├── print.rs
│   │   └── user.rs // user会调用print的方法
│   ├── multip  // ------- 新增这个模块
│   │   ├── mod.rs法
│   ├── lib.rs

multip/mod.rs

pub fn res_multip(a: i32, b: i32) -> i32 {
    a * b
}

假设add文件引入multip

mod print;
mod user;

pub use self::user::hello_user;
pub use self::user::User;
// 新增下面这行
use crate::multi::multip;

如此便可以使用另一个模块的内容了。当然其他模块的相互引用方式一致。

小结

rust的模块使用方式总体来说是比较简单的,由于官方文档在模块拆分和组织上并没有进行较完善的说明,所以对于刚从js转到rust学习的同学可能会有一点不适应。通过前面内容已经较为清晰的梳理了下使用方式。希望可以对需要的同学有所帮助。

到此这篇关于Rust模块使用方式的文章就介绍到这了,更多相关Rust模块使用方式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

深入讲解下Rust模块使用方式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python hashlib模块详细讲解使用方法

hashlib 是一个提供了一些流行的hash算法的 Python 标准库.其中所包括的算法有 md5, sha1, sha224, sha256, sha384, sha512. 另外,模块中所定义的 new(name, string=”) 方法可通过指定系统所支持的hash算法来构造相应的hash对象
2022-11-13

深入解析Python编程中JSON模块的使用

JSON编码支持的基本数据类型为 None , bool , int , float 和 str , 以及包含这些类型数据的lists,tuples和dictionaries。 对于dictionaries,keys需要是字符串类型(字典中
2022-06-04

深入学习nodejs中的async模块的使用方法

最近在学习nodejs,这两天学习了async模块这个地方知识点挺多的,所以,今天添加一点小笔记。 async模块是为了解决嵌套金字塔,和异步流程控制而生.常用的方法介绍npm 安装好async模块,然后引入就可以使用 var async
2022-06-04

深入解析Python设计模式编程中建造者模式的使用

建造者模式:将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。 基本思想 某类产品的构建由很多复杂组件组成; 这些组件中的某些细节不同,构建出的产品表象会略有不同; 通过一个指挥者按照产品的创建步骤来一步步执行产品的
2022-06-04

Golang反射模块reflect使用方式示例详解

Golang的反射功能,在很多场景都会用到,最基础的莫过于rpc、orm跟json的编解码,更复杂的可能会到做另外一门语言的虚拟机,这篇文章主要介绍了Golang反射模块reflect使用方式探索,需要的朋友可以参考下
2023-01-04

实例讲解Python设计模式编程之工厂方法模式的使用

工厂方法模式是简单工厂模式的进一步抽象和推广,它不仅保持了简单工厂模式能够向客户隐藏类的实例化过程这一优点,而且还通过多态性克服了工厂类过于复杂且不易于扩展的缺点。在工厂方法模式中,处于核心地位的工厂类不再负责所有产品的创建,而是将具体的创
2022-06-04

使用Mixin设计模式进行Python编程的方法讲解

Mixin模式是一种在python里经常使用的模式,适当合理的应用能够达到复用代码,合理组织代码结构的目的。 Python的Mixin模式可以通过多继承的方式来实现, 举例来说,我们自定义一个简单的具有嵌套结构的数据容器:class Sim
2022-06-04

Android中使用PULL方式解析XML文件深入介绍

一、基本介绍 Android中极力推荐xmlpull方式解析xml。 xmlpull不仅可用在Android上同样也适用于javase,但在javase环境中需自己获取xmlpull所依赖的类库,kxml2-2.3.0.jar,xmlpul
2022-06-06

python操作excel之openpyxl模块读写xlsx格式使用方法详解

这篇文章主要介绍了python操作excel之openpyxl模块读写xlsx格式使用方法详解,需要的朋友可以参考下
2022-12-21

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录