【Rust中的项目管理】

server/2024/11/19 22:53:03/

Rust中的项目管理

  • 前言
  • Package,Crate,Module &use ,Path
  • 通过代码示例解释 Crate,Module ,use,Path
      • 创建一个package:
      • 代码组织化
      • skin.rs 中的代码
        • struct & enum
      • 相对路径和绝对路径
      • 引用同名模块怎么办?
      • use
      • pub use


前言

在开发者进行项目立项并逐步开发时,尤为重要的是项目结构和各个模块的管理,在C++中,通常我们结合文件夹以及namespace和头文件的共同作用下将项目结构变得合理,Rust为开发者提供了一整套管理体系如Package,Crates,Module &use ,Path,通过这些特性来共同管理Rust项目,开合自如。

Package,Crate,Module &use ,Path

package:Cargo Feature,可用于build crate,share create & test Crate。
Crate:Rust编译器可编译的最小块,可编译出二进制文件或者库,crate在写法上便是模块树,包含了一系列具有相关性的代码,通过目录和mod关键字组合而成。
Module &use : 在整个工程中起到组织,限制,控制代码隐私的作用
Path: 描述所需具体模块以及方法所在位置的手段,结合use达到C++中的include 效果。

通过代码示例解释 Crate,Module ,use,Path

创建一个package:

rust">cargo new mypackage --lib

可以看到如下的目录结构:
在这里插入图片描述
上述便是package的具体表现形式,package允许libraries和execute同时存在,但是在一个package中,只能有一个lib,可以有多个executes,但是不论如何,package一定要包含一个crate,不论是 binary or library。
在省略–lib的状态下, 会在src中直接创建 一个main.rs,加上–lib 创建项目时会在src中创建一个lib.rs ,不论是lib.rs还是main.rs都是crate root,既模块树的树根,抑或是package编译每一个crate的入口root,cargo会将跟文件传递给rustc从而进行编译lib.rs对应与package同名的库,main.rs对应与package同名的二进制可执行文件。

代码组织化

示例工程结构如下:
在这里插入图片描述
rust中的模块树如同操作系统中的目录树结构一样,依赖文件夹以及文件夹命名,如图中所示绿色框中的hairs.rs 与文件夹hairs,一般情况下,为了工程代码的整洁,通常不会将所有的代码放在hairs.rs 中,但是需要设计的层级关系,如图中关系,hair->skin->bones,在工程中就可以像图中一样处理,简单来讲 就是子模块放在父模块同级同名文件夹内部,代码文件名xxx.rs在Path 既寻找指定代码依赖时同样重要。 古早的写法:/xxx/xxx/mod.rs现在依然支持但是不再推荐了。可以这样简单的理解,模块名称仅和文件名称、mod xxx 有关,文件夹只是寻路以及整理文件的作用。

skin.rs 中的代码

rust">pub mod bones;pub mod muscle {#[derive(Debug)]pub struct Muscle {pub name: String,pub muscle_group: String,}impl Muscle {pub fn new(name: &str, muscle_group: &str) -> Muscle {Muscle {name: name.to_string(),muscle_group: muscle_group.to_string(),}}pub fn get_muscle_group(&self) -> &str {&self.muscle_group}pub fn get_name(&self) -> &str {&self.name}}
}
pub mod fat {#[derive(Debug)]pub struct Fat {pub percentage: f64,}impl Fat {pub fn new(percentage: f64) -> Self {Fat { percentage }}fn get_percentage(&self) -> f64 {self.percentage}}
}

可以看到,在这里我们将bones模块暴露出去,并在skin包内部定义了Muscle 和 Fat 模块以及结构体和方法。
需要注意的是,模块默认的内部全部都是私有化的,所以如果不加上pub,外部无法访问使用。

struct & enum

struct 内部私有,enum内部pub,这是他们的不同之处。

相对路径和绝对路径

与目录结构一样,我们既可以使用绝对路径也可以使用相对路径use 我们需要的模块,如何选择?根据现实情况,当N个module在同一个父模块中,使用super简单快捷, self一般个人不是很喜欢用,当module来源于父模块之外,用绝对路径。对于引用模块中的函数来讲,直接引入函数的父模块更方便,一般情况下你不会仅使用一个模块中的一个方法,除非你的代码出现了什么设计上的问题,但是如果是使用结构体容器之类,那最好是包含到最后一层。
还记得我们再创建工程时生成的lib.rs吗?来看看其内部代码:

rust">mod Body;
pub mod body;
pub mod cloths;
pub mod hairs;
pub fn add(left: u64, right: u64) -> u64 {left + right
}#[cfg(test)]
mod tests {use super::*;#[test]fn it_works() {let result = add(2, 2);assert_eq!(result, 4);}
}

这里的use super::*;便是使用模块中的所有子模块,为了unit test,关于uint test ,已经在Rust中的测试一章细聊过。

引用同名模块怎么办?

Rust中,你可以在使用时用全路径,亦或使用as 起个别名,具体的,这没有约定俗成的建议,完全取决于开发者的习惯。
代码示例:

rust">use std::io::Result as IoResult;

use

代码示例:

rust">use mypackage::{body, cloths::Cloths, hairs::skin::muscle::Muscle};
fn main() {let hair_color = Muscle::new("kangkang", "groupOne");println!("{:?}", hair_color.get_muscle_group());let cloth = Cloths::new("skirt", "yellow");println!("{:?}", cloth.get_name());let mybody = body::Body::new();mybody.show();
}
rust">use crate::hairs::skin::bones;
use crate::hairs::skin::{fat, muscle};
#[derive(Debug)]
pub struct Body {my_bones: bones::Bones,my_fat: fat::Fat,my_muscle: muscle::Muscle,
}impl Body {pub fn new() -> Self {Body {my_bones: bones::Bones::new("humanBones", 206),my_fat: fat::Fat::new(15.0),my_muscle: muscle::Muscle::new("muscle", "arms"),}}pub fn show(&self) {println!("{:?}", &self);}
}

pub use

这里既是开放使用某个模块,使用它相当于开发者在使用处直接“创建”了这个模块,在使用时便只需引用到使用处的模块即可,这多数用在我们自己编写crate时候,由于封装性我们将很多数据结构封装的很深,而使用方又不得不使用,而我们又不想暴露更多细节给到用户,尤其是module层级较深时,对于使用者也是一个难题,pub use便可以很好的解决这样的问题。

“每天怎么过,都是我们的选择”


http://www.ppmy.cn/server/143315.html

相关文章

基于C语言easyX实现的推箱子游戏

基于80x86汇编语言的推箱子游戏 一、游戏背景介绍 推箱子是一款众所周知的益智游戏,此游戏只有一个目标:将游戏中的所有箱子推到指定位置。简单易懂的游戏规则是此款游戏成功的根本原因。 此游戏具有如下特点:简便的操作、复杂的关卡以及层…

20241114软考架构-------软考案例15答案

每日打卡题案例15答案 15.【2016年真题】 难度:一般 阅读以下关于应用服务器的叙述,在答题纸上回答问题1至问题3。(25分) 【说明】 某电子产品制造公司,几年前开发建设了企业网站系统,实现了企业宣传、产品…

学习笔记023——Ubuntu中设置Java项目的 jar 包自启动

目录 1、设置 crontab 定时任务 2、定时脚本 startJar.sh内容 3、查看jar包进程 4、如何杀死进程 背景:有个需求,Ubuntu服务器中,虽有Java环境,但是没有tomcat。 想要运行jar包,只能通过java -jar命令了。 但是我…

基于 Python Django 的二手房间可视化系统分析

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

小程序-基于java+SpringBoot+Vue的实习生管理系统设计与实现

项目运行 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…

使用GDB或Delve对已经运行起来的Go程序进行远程调试

同步发布在我的博客,欢迎来点赞。 使用 GDB 或 Delve 对已经运行起来的 Go 程序进行远程调试 使用 GDB 或 Delve 对已经运行起来的 Go 程序进行远程调试 背景 Java 程序可以很方便地通过 jdwp 参数指定一个对外端口进行远程调试,如 java \ -agentlib…

菜鸟驿站二维码/一维码 取件识别功能

特别注意需要引入 库文 ZXing 可跳转: 记录【WinForm】C#学习使用ZXing.Net生成条码过程_c# zxing-CSDN博客 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Net.…

Android WMS概览

WMS(WindowManagerService)是 Android 系统的核心服务,负责管理应用和系统的窗口,包括窗口的创建、销毁、布局、层级管理、输入事件分发以及动画显示等。它通过协调 InputManager 和 SurfaceFlinger 实现触摸事件处理和窗口渲染&a…