【Rust模块管理】Rust包、crate与模块管理

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Rust开发,Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:Rust语言通关之路
景天的主页:景天科技苑

在这里插入图片描述

1、名词定义

包:Cargo的一个功能,允许构建,测试,和分享crate。
crate:一个模块的树形结构,形成库或二进制项目。
模块:通过use来使用,用来控制作用域和路径的私有性。
路径:一个命名 例如结构体、函数或模块等项的方式
在 Rust 中,模块(module)是组织代码的基础单位,它帮助你将代码划分为多个逻辑部分,便于管理、复用和控制访问权限。
模块是一个命名空间,用于组织函数、结构体、枚举、常量、trait 和其他模块。Rust 中的模块可以嵌套,并且支持私有和公开访问控制。

2、包和crate

(1) crate root 是一个源文件,Rust 编译器以它为起始点,并构成你的 crate 的根模块。
(2) 包提供一系列功能的一个或多个Crate。
(3) Crate root是src/main.rs或者是src/lib.rs。说明: 如果只有main.rs则说明这个包只有一个crate(main),如果同时拥有main.rs和其它的lib.rs(不一定是这个名字)则说明拥有多个crate。
(4) crate会将一个作用域的相关功能分组到一起,使得该功能可以很方便的在多个项目之间共享。

3、Rust模块

3.1 模块的定义与作用

模块(Module)是Rust中代码组织的基本单元,主要功能包括:
命名空间管理:防止命名冲突
封装性:通过pub关键字控制可见性
代码组织:将相关功能逻辑分组
编译单元:影响编译过程和代码生成

3.2 基本语法

在Rust中,使用mod关键字定义模块:

mod my_module {
    // 模块内容
}

模块可以包含函数、结构体、枚举、trait、其他模块等。

3.3 模块的可见性

Rust默认所有项(item)都是私有的,只在当前模块内可见。使用pub关键字可以使其对外可见:

mod my_module {
    pub fn public_function() {
        println!("This is public");
    }
    
    fn private_function() {
        println!("This is private");
    }
}

3.4 模块的多种定义方式

3.4.1 内联模块

直接在文件中使用mod关键字定义:

//定义模块
mod factory {
    //如果对外暴露模块,都得使用pub
    pub mod prduct_car {
        pub fn new_car() {
            println!("new car");
        }
    }

    pub mod product_bike {
        pub fn new_bike() {
            println!("new bike");
        }
    }
}

fn main() {
    //使用模块
    factory::prduct_car::new_car();
    factory::product_bike::new_bike();
}

在这里插入图片描述

3.4.2 文件模块

更常见的做法是将模块放在单独的文件中。
方式一:添加模块文件
直接在项目src下,创建个rs文件network.rs

pub fn connect() {
    println!("connect");
}
pub fn disconnect() {
    println!("disconnect");
}
pub fn send() {
    println!("send");
}
pub fn receive() {
    println!("receive");
}

在这里插入图片描述

直接在main.rs中使用mod引用

mod network;
fn main() {
    network::connect();
    network::send();
    network::receive();
    network::disconnect();
}

在这里插入图片描述

方式二:添加库
我们在cargo创建的项目目录下,通过cargo new --lib mylib 创建一个库
在这里插入图片描述

我们创建的库里面的lib.rs文件中有测试模块
在这里插入图片描述

在我们创建的库mylib的src下创建个文件模块factory.rs,将之前通过内联模式创建的模块代码拿过来
在这里插入图片描述

在lib.rs中导出我们创建的模块

//在lib.rs中导出我们创建的模块
pub mod factory;

在这里插入图片描述

然后,在我们得项目的Cargo.toml文件中,将我们创建的库的路径指定
在[dependencies]下面添加
在这里插入图片描述

main.rs中导入我们创建的库,并使用
在这里插入图片描述

3.4.3 目录模块

对于更复杂的模块,可以使用目录形式。例如,创建一个client模块:
src/
├── client/
│ ├── mod.rs
│ ├── http.rs
│ └── tcp.rs
├── main.rs

http.rs
在这里插入图片描述

tcp.rs
在这里插入图片描述

mod.rs是目录模块的入口文件:
导出模块http和tcp

// client/mod.rs
pub mod http;
pub mod tcp;

然后在main.rs中使用

mod client;
fn main() {
    //注意,在http.rs中导出模块名http,在mod.rs中又导出http模块名,所以相当于又两层http模块名
    client::http::http::get();
    client::tcp::tcp::connect();
}

在这里插入图片描述

3.5 模块路径与use关键字

3.5.1 绝对路径与相对路径

Rust中有两种引用模块项的路径:
绝对路径:从crate根开始,使用crate::或外部crate名称
相对路径:从当前模块开始,使用self::、super::或直接使用标识符

mod client {
    pub mod http {
        pub fn connect() {}
    }
}

// 绝对路径
crate::client::http::connect();

// 相对路径
client::http::connect();

3.5.2 use关键字

use关键字用于将路径引入作用域,简化代码:

use client::http;

http::connect();

可以使用as创建别名:

use std::io::Result as IoResult;

起别名
在这里插入图片描述

高级用法:

// 嵌套路径
use std::{cmp::Ordering, io};
// 引入多个项
use std::collections::{HashMap, HashSet};
// 引入所有公共项(谨慎使用)
use std::collections::*;

3.6 重导出

重导出允许你公开模块内部的项,并为其提供新的路径:

// src/lib.rs
mod internal {
    pub mod network {
        pub fn connect() {}
    }
}

pub use internal::network::connect;

现在用户可以直接使用crate::connect()而不是crate::internal::network::connect()。

3.7 访问控制与可见性

3.7.1 可见性修饰符

Rust提供了精细的可见性控制:
pub - 完全公开
pub(crate) - 当前crate内可见
pub(super) - 父模块中可见
pub(in path) - 指定路径中可见

示例:

mod outer {
    pub mod inner {
        pub(in crate::outer) fn restricted() {}
        
        pub fn example() {
            restricted(); // 可以访问
        }
    }
    
    pub fn test() {
        inner::restricted(); // 可以访问
    }
}

fn main() {
    outer::inner::example();
    // outer::inner::restricted(); // 错误:不可见
}

3.7.2 结构体与枚举的可见性

结构体字段需要单独控制可见性:
使用内联模块来创建结构体

//内联模块
mod mystruct {
    #[derive(Debug)]
    pub struct MyStruct {
        pub username: String,
        pub age: i32,
        money: i32, //私有字段
    }

    //实现MyStruct的构造函数和方法
    impl MyStruct {
        //构造函数,其实就是一个关联函数
        pub fn new(username: String, age: i32) -> MyStruct {
            MyStruct { username, age, money: 9999990 }
        }

        //方法
        //方法的第一个参数是&self,表示调用该方法的实例
        pub fn display(&self) {
            println!("username: {}, age: {}, money: {}", self.username, self.age, self.money);
        }
    }
}

//使用模块
use mystruct::MyStruct;
fn main() {
    let mystruct = MyStruct::new("jingtian".to_string(), 18);
    mystruct.display();
}

在这里插入图片描述

公有字段可以访问,私有字段不能访问
在这里插入图片描述

在这里插入图片描述

枚举的变体继承枚举的可见性:

pub enum HttpStatus {
    Ok,           // 公开
    NotFound,     // 公开
    ServerError,  // 公开
}

3.7.3 通过super访问父级模块

//内联模块
mod mystruct {
    pub mod mod_b {
        pub fn display() {
            println!("hello, B");
        }
        //子模块
        pub mod mod_c {
            pub fn print_c() {
                println!("hello, C");
                //子模块访问父模块方法
                super::display();
            }
        }
    }
}

//使用模块
// use mystruct::MyStruct;
use mystruct::mod_b;
fn main() {
    //子模块访问父模块方法
    mod_b::mod_c::print_c();
}

子模块mod_c中的print_c方法,调用了父模块mod_b的print_b方法。
因此也打印了 hello, B
在这里插入图片描述

4、第三方库管理

上面都是我们自己写的库,如果我们使用别人写好的库该怎么使用呢?比如加密库等
Rust语言的库的官方网站crate,可以登录这个网站查找你想要的第三方库
https://crates.io/
在这里插入图片描述

需要修改Cargo.toml文件,来实现加载第三方库
比如我们需要rand库
直接搜索
在这里插入图片描述

直接复制这个版本到Cargo.toml文件的dependencies下面
在这里插入图片描述

放到dependencies下面,保存后就会自动加载依赖
在这里插入图片描述

但是不推荐直接这种方式安装第三方库
我们使用cargo-edit这个插件
安装

cargo install cargo-edit   

添加库

cargo add dependency_name    //最新版
#安装指定版本
cargo add dependency_name@1.2.3

在这里插入图片描述

#添加开发时用的依赖库
cargo add --dev dev dependency_name
#添加构建时用的依赖库
cargo add --build build dependency_name
#删除库
cargo rm dependency_name

在这里插入图片描述

#删除dev的库
cargo rm --dev dependency_name
#删除build的库
cargo rm --build dependency_name

设置国内源
推荐使用https://rsproxy.cn/。这个库比较全,速度也比较快
在这里插入图片描述

Linux和Mac修改 ~/.cargo/config 
[source.crates-io]
replace-with = 'rsproxy-sparse'
[source.rsproxy]
registry = "https://rsproxy.cn/crates.io-index"
[source.rsproxy-sparse]
registry = "sparse+https://rsproxy.cn/index/"
[registries.rsproxy]
index = "https://rsproxy.cn/crates.io-index"
[net]
git-fetch-with-cli = true

Windows设置国内源:
安装方式不同
windows可选Rust 的目标平台标识
x86 64-pc-windows-msvc //可以通过rustup show查看自己安装的版本
x86_64-pc-windows-gnu(不推荐)
rustup component
某些组件可能不同
设置国内源的文件路径不同,将上述文件配置到下方config即可
C:\Users<你的用户名>.cargo\config

在这里插入图片描述

第三方库使用案例:
我们使用加密库rust-crypto
先登录 https://crate.io
查找该库
在这里插入图片描述

通过cargo add来安装
在这里插入图片描述

cargo add rust-crypto
安装完之后,会在Cargo.toml文件中的dependencies中自动生成依赖和版本。我们就可以使用了
在这里插入图片描述

使用第三方库

//extern crate是edition 2018之前的用法
extern crate crypto;   //edition 2018以及之后的版本不用加这个
use crypto::digest::Digest;
use crypto::sha3::Sha3;
fn main() {
    //使用第三方库
    let mut hasher = Sha3::sha3_256();
    hasher.input(b"hello world");
    let result = hasher.result_str();
    println!("SHA3-256 hash: {}", result);
}

在这里插入图片描述

edition 2018以及之后的版本用法
在这里插入图片描述

评论 45
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

景天科技苑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值