16. rust项目管理

一、前言

前面我们已经使用了很多别人写的包,而本文就将详细介绍我们如何去写一个属于自己的包。

包的作用相信大家已经有所领悟:可以共享常用代码,避免大家造轮子。

在rust中,包的别名是crate,而crate则是rust编译的最小代码单位,比如我们前面写的main.rs中的代码,最终会被编译为一个二进制可执行文件。

main.rs文件中的代码此时就属于我们自定义项目的一个源代码文件。

类比之下,其实它这里这个包的概念与vs中解决方案的概念很类似,而crate就像是vs中的各个项目。

没错,二进制项目在rust中同样也被称为crate,除了二进制外,当然也还有更常见的库,比如动态库与静态库

总的来说,rust中将项目一共分为了四个层次:工作空间、crate、模块、源码文件

graph LR
P[工作空间]-->A[多个crate]
A-->B[二进制]
A-->C[库]
B-->f1([多个模块])
C-->f1([多个模块])
f1-->f2([源代码文件1])
f1-->f3([源代码文件2])
f1-->f4([......])

一个工作空间可以包含多个crate,而crate可以被分为二进制和库两种。

每个crate都是由多个模块组成的,并且一个模块可以由多个源文件组成。

但一般我们并不这样做,更多的时候,至少我个人更喜欢让一个源文件对应一个模块,方便整理,而文件名就是模块名。

二、模块

我们从底层往上层看,首先是模块,虽然前面我说大多数时候我都更喜欢一个文件对应一个模块,但你也可以不这样做:

image-20231216084941927

比如上面这样,就属于内联方式,直接用mod关键字声明一个模块,然后将函数、结构体等写在其内部就行了。

但此时要注意,模块中的东西默认都是私有的,如果想要让模块外使用,就必须添加pub关键字。

使用方式就是模块名::,后面紧跟其内部写的东西就行了。

是不是和C++的类中静态函数挺像的?默认私有,需要添加public关键字暴露,使用的时候是类名::函数名

所以说其实学了C++,其它语言都大差不差,很多时候只是换了一个概念而已。

上面这种内敛方式用的极少,大多数时候我们都是一个文件对应一个模块:

image-20231216085606648

但要注意,这样情况下,我们必须还要在main.rs文件中声明一下,此时模块名就是文件名。

而该源文件中除了记住所有内容都是私有的外,其它也就没什么了,想要让其它模块使用就必须得添加pub关键字。

与之等价的方式是同名文件夹下的mod.rs源文件:

image-20231216090014839

注意mod.rs这个名字和main.rs一样,都是官方制定好的,不能修改,此时模块名字就是这个文件夹。

这样写看起来似乎变得更加繁琐了,但也是有其原因的,因为这样写可以方便我们继续添加子模块: image-20231216090453261

此时就开始套娃了,因为我又在test模块中添加了一个子模块,名为submod,以单文件方式存在的,当然你依旧可以将其写为文件夹的方式,然后继续套娃。

然后声明子模块就需要在其父模块中进行声明,比如这里就是在test模块中mod.rs文件中进行的声明。

注意如果想要让子模块被外面使用,依旧需要添加关键字pub

那么此时,在主模块main.rs中就可以通过层层调用的方式,调用test模块中的submod模块中的sub_mod_fun函数。

是不是还是挺简单的!rust直接将文件目录结构解析为模块之间的包含关系,可以让我们非常方便的管理项目文件。

但在这种子模块嵌套过多的情况下,会导致外面使用起来很费力,此时就可以使用use关键字:

image-20231216091050144

use关键字的逻辑其实也非常简单,只要使用了哪个,那么在它的作用域下,你就可以直接使用它了,

比如这里,因为use test::submod,所以代码中就可以直接使用submod了,这种方式可以让我们少写很多代码。

最后一个与模块相关的东西是主模块,也就是我们main.rs文件对应的模块,被默认命名为了crate,也常被称为根模块:

image-20231216091407555

所以上图的写法与前面是等价的,本crate中的所有模块,都可以通过crate这个模块访问到,它是根模块。

至于说同模块分文件写,基本上是没有必要的,因为你完全可以按照功能将其划分为子模块,这样还更方便管理,所以这里就不再讲解了,至少我很少有这种需求。

三、lib

讲完模块,下面就可以来到crate了,crate可以分为两种,一种是二进制的,也就是前面我们一直使用的。

而另一种则是lib形式,平时我们在依赖项中添加别人写的库,实际上都是引用的别人写的lib形式。

在rust中写lib依旧非常简单,你可以直接通过下面这个命令完成一个lib crate的添加,但要注意,这是在新建一个crate,不要在原来的二进制crate中使用:

cargo new --lib libtest

这与新建一个二进制crate方式是一样的,只是加了一个选项--lib而已,最后的那个是我们lib crate的名字,可以自己随意修改。

此时其默认生成了以下代码与文件:

image-20231216092235109

注意lib crate的入口文件也不一样了,是lib.rs,而二进制 crate则是main.rs

由于lib本身是无法运行的,它只能依赖于其它二进制crate才能运行,但为了方便写lib时进行调试,rust就提供了一个叫做测试的功能。

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux