Rust 模块系统

news2024/9/24 1:21:08

文章目录

  • 模块系统
    • crate
    • cargo 创建库
    • 库的使用

模块系统

Rust的{模块系统|the module system},包括:

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

crate

crate 是 Rust 在编译时最小的代码单位。如果用 rustc 来编译一个文件,编译器就会将那个文件认作一个 crate。crate 可以包含模块,模块可以定义在其他文件,然后被编译进 crate 。

crate 有两种形式:二进制项和库。
第一种形式的二进制项可以被编译为可执行程序(exe)。它必须有一个 main 函数来作为入口函数。前面的每段代码段运行时都是编译成了一个二进制项。
第二种形式就是库,库其实就是工具包,只不过它提供的工具是函数/类/结构体/空间等等,它没有 main 函数,也不会编译为可执行程序,只能编译出类似于 dll/lib 之类的文件。大多数情况下 Rust 开发者说的 crate 指的都是库。库的入口为 lib.rs 。

在Rust中,包(package)是用于组织、管理和分发 Rust 代码和库的一种结构。Cargo 就是 Rust 用来管理包的工具,用 cargo 生成一个包时会含有一个 Cargo.toml 文件,阐述如何构建包含有的 crate。开发者还可以将包发布到crates.io,以供其他人使用。

一个包可以包含多个二进制 crate 项和一个可选的 crate 库。包中所包含的内容由几条规则来确立。

* 一个包中至多只能包含一个{library crate};
* 包中可以包含任意多个{binary crate};
* 包中至少包含一个 crate,无论是库还是二进制。

cargo 创建库

二进制项也就是exe前面用了很多了,这次用 cargo 创建一个 lib 工程,通过 new 指令,指定类型为lib,然后就可以得到这样一个工程:
在这里插入图片描述

与普通工程不一样的是main.rs变成了 lib.rs,然后看一下这里的代码:
首先定义了一个名为 add 的函数,它接受两个usize类型的参数,返回一个usize类型的结果,关于 pub:

在Rust中,pub是一个关键字,用于指示项的可见性。当一个函数、结构体、枚举或其他项前面带有pub关键字时,它表示该项是公开的(public),可以从该项的父模块或父作用域之外的地方访问和使用。
通过使用pub关键字,开发者可以控制项的可见性,确保某些项只能在特定的模块或作用域内使用,而不会被外部代码随意访问。这种可见性控制有助于代码的组织和封装,提供了更好的模块化和安全性。
简而言之,pub关键字用于将Rust项标记为公开的,以便可以在更广泛的范围内使用和访问。
这个后面学作用域会学到

后面的是自动生成的关于测试的代码:

#[cfg(test)]  // 使用#[cfg(test)]属性标记下面的代码块只在执行测试时编译和运行  
mod tests {  
    // 使用super::*导入父作用域中的所有公共项,以便在测试模块中使用add函数  
    use super::*;  
  
    // 定义一个测试函数it_works  
    #[test]  
    fn it_works() {  
        // 调用add函数并将结果赋值给result变量  
        let result = add(2, 2);  
        // 使用断言宏assert_eq!来检查result是否等于4,如果不等于,测试将失败  
        assert_eq!(result, 4);  
    }  
}

然后执行,cargo build, 就会发现 target 下生成了一些文件:
在这里插入图片描述

其中.d文件是用于依赖跟踪的。这个文件由编译器生成,并包含了源代码文件中使用的依赖信息。主要用于构建系统中,以确保在源代码文件更改时,所有依赖该文件的其他文件也会被重新构建。.d文件包含了源代码文件与其依赖项之间的关系,这样构建系统就可以准确地知道哪些文件需要重新编译,以及哪些文件可以跳过编译。这种做法可以提高构建的效率,因为只有需要重新编译的文件才会被构建,而不会被重新编译的文件则会被跳过。

.rlib文件就是 Rust 的静态库文件。这个文件包含了代码的编译结果,并可以用于链接到其他 Rust 项目中,供其他项目使用。.rlib文件包含了库的元数据和编译后的代码,它们是以平台无关的方式生成的,因此可以在不同的操作系统和架构上使用。

库的使用

刚开始我以为 Rust 里的库和C++里的一样,是直接拿过来用的,但是试了很久也没办法在本地只使用 .rlib 文件而不是用源码执行成功,如果有哪位大佬知道如何仅在工程中引入 .rlib 的方式请评论说一下,万分感谢;
另外在论坛看到有人说:

dependencies expects a Cargo package, which it will build as part of the larger build.
An rlib is the final product of a compilation step. Cargo passes them around under the hood to rustc.
So the question is: what are you really trying to do there? What does your project look like and why do you think using an rlib directly is the way to go?

You can't use rlib with Cargo. Rust doesn't have a stable ABI, so you pretty much can't use them at all. Threat them as an internal implementation detail of Rust that is not for users.

似乎是因为没有C++的头文件导出的类似的机制,导致无法直接使用rlib ,因为使用者无法知道库中都提供了那些工具。

使用方式就是将库代码放在程序的目录下, 然后在 Cargo.toml 文件中,添加对库的引用,可以在dependencies部分添加一行,指定库的名称和路径,比如:

[dependencies]
hellolib = { path = "../hellolib" }

然后在,main.rs 中 extern crate hellolib; 就可以在代码中使用了;
具体目录层级与代码如下:
在这里插入图片描述

还有通过 crates.io 与 git 来引入库,这部分后续再补充;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1140969.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Uva】10976-Fractions Again?!

1、题目 2、题意 输入正整数 k k k,找到所有正整数 x ≥ y x \ge y x≥y,使得 1 k 1 x 1 y \frac{1}{k} \frac{1}{x} \frac{1}{y} k1​x1​y1​。 3、分析 既然要求找出所有的 x , y x,y x,y,枚举对象自然是 x , y x,y x,y了。可…

有用过成绩查询系统的老师吗?

是不是有时候觉得手动查询成绩是一件超级繁琐的事情?有了这个成绩查询系统,你就可以告别手动时代啦! 先来了解一下什么是成绩查询系统。成绩查询系统是一种可以自动查询学生成绩的系统。通过这个系统,学生可以输入自己的学号或姓名…

使用管理员其权限打开cmd,如何切换到其他磁盘

问题描述: 切换到 O:\BaiduSyncdisk\develope\mysql-8.0.31-winx64 ,直接使用cd命令切换失败。 原因是因为,在使用管理员身份打开cmd的时候,只能切换到当前盘符下的目录,而不能切换到其他盘符下的目录。 解决方案&am…

Android原生项目集成uniMPSDK(Uniapp)遇到的报错总结

uni小程s序SDK 集成到Android原生项目:老项目中用到的库较多,会出现几种冲突问题,总结如下: 报错1: Execution failed for task :app:processDebugManifest. > Manifest merger failed with multiple errors, see logs Andro…

mac idea 问题

运行springboot工程时突然idea就崩了,然后再打开maven的小窗口都没了,怎么都出不来。一气之下重装idea 发现都不行。后来发现是没清理干净之前的配置。 /Users/你的用户名/Library/Application\ Support/JetBrains 这个文件夹下清理掉之后,重…

单片机为什么一直用C语言,不用其他编程语言?

单片机为什么一直用C语言,不用其他编程语言? 51 单片机规模小得拮据,C 的优势几乎看不到。放个类型信息进去都费劲,你还想用虚函数?还想模板展开?程序轻松破 10k。最近很多小伙伴找我,说想要一些…

数据库SqlServer面试题不完全总结

数据库SqlServer面试题不完全总结 一、数据库基础知识(通用)篇 1.说说主键、外键、超键、候选键 超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属 性组合在一起也可以作为一个超键…

[debug/main.o] Error 1 QtCreator编译报错

在我是用Qt5.6.0MinGW32位版本编译程序,在Pro文件中添加了预编译头文件后编译报错:mingw32-make[1]: *** [debug/main.o] Error 1; #添加预编译头文件 CONFIG precompiled_header PRECOMPILED_HEADER header.h 解决方法: 1.删…

分布式消息队列:RabbitMQ(1)

目录 一:中间件 二:分布式消息队列 2.1:是消息队列 2.1.1:消息队列的优势 2.1.1.1:异步处理化 2.1.1.2:削峰填谷 2.2:分布式消息队列 2.2.1:分布式消息队列的优势 2.2.1.1:数据的持久化 2.2.1.2:可扩展性 2.2.1.3:应用解耦 2.2.1.4:发送订阅 2.2.2:分布式消息队列…

墨西哥专线空运载重限制是多少?

在国际贸易中,物流运输是至关重要的一环。对于需要将货物运输至墨西哥的客户来说,了解墨西哥专线空运的载重限制是非常必要的。本文将为您详细解析墨西哥空运的相关知识。 一、墨西哥专线空运简介 墨西哥专线空运是指通过专门的航空公司或货运代理公司&…

SSM咖啡点餐管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM 咖啡点餐管理系统是一套完善的信息系统,结合SSM框架完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具有完整的源代码和数据库,系统主 要采用B/S模式开…

​iOS安全加固方法及实现

目录 iOS安全加固方法及实现 摘要 引言 iOS安全加固方法及实现 一、字符串加密 二、类名方法名混淆 三、程序代码混淆 四、加入安全SDK 总结 参考资料 摘要 本文介绍了iOS平台下的应用安全保护方法,包括字符串加密、类名方法名混淆、程序代码混淆和加入安全…

贪吃蛇-c语言版本

目录 前言 贪吃蛇游戏设计与分析 设计目标: 设计思想: 坐标问题: 字符问题: 小拓展:C语⾔的国际化特性 本地化头文件: 类项 setlocale函数: 宽字符打印: 地图坐标: &am…

如何创建加载项(1)

《VBA高级应用30例》(10178985),是我推出的第十套教程,教程是专门针对高级学员在学习VBA过程中提高路途上的案例展开,这套教程案例与理论结合,紧贴“实战”,并做“战术总结”,以便大…

智安网络|揭秘安全测试和渗透测试的异同点

随着云计算的兴起,企业网络安全面临着新的挑战。为了保护企业的核心资产和数据安全,堡垒机作为一种重要的安全设备被广泛应用。传统的堡垒机在过去几十年中发挥了重要作用,但如今,随着云堡垒机的出现,企业在选择合适的…

BLE基础

文章是视频笔记 蓝牙广播 教程讲义 ESP32之低功耗蓝牙(BLE)-小鱼创意 蓝牙信道 BLE(Bluetooth Low Energy)广播使用的是2.4GHz ISM频段,其中包含了40个信道。在BLE广播中,主要使用的是3个不相邻的信道&…

2023年第四届MathorCup大数据竞赛(A题)|坑洼道路检测和识别|数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时,你是否曾经感到茫然无措?作为2021年美国大学生数学建模比赛的O奖得主,我为大家提供了一套优秀的解题思路,让你轻松应对各种难题。 希望这些想法对大家的做题有一定的启发和借鉴意义。 让我们来…

普及篇|云备份和云容灾,你用对了吗?

企业常常会因为自然灾害、硬件老化故障、人为误操作等问题导致业务系统中断,该如何进行安全、高效的数据保护,这一问题引起企业越来越多的高度关注。 而对比传统的自建机房对数据进行保护,在云端利用云计算的弹性伸缩、按需扩展特点&#xff…

公众号迁移如何线上办理公证?

公众号账号迁移的作用是什么?只能变更主体吗?1.可合并多个公众号的粉丝、文章,打造超级大V2.可变更公众号主体,更改公众号名称,变更公众号类型——订阅号、服务号随意切换3.可以增加留言功能4.个人订阅号可迁移到企业名…

实现寄生组合继承

寄生组合继承是一种继承方式,它通过组合使用构造函数继承和原型继承的方式,实现了高效而且正确的继承方式。 具体实现步骤如下: ① 定义一个父类,实现其属性和方法: function Person(name) {this.name namethis.age…