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

06-02 693阅读

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

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

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

🏆 作者简介:景天科技苑

🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。

🏆《博客》:Rust开发,Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:Rust语言通关之路

景天的主页:景天科技苑

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

文章目录

  • 1、名词定义
  • 2、包和crate
  • 3、Rust模块
    • 3.1 模块的定义与作用
    • 3.2 基本语法
    • 3.3 模块的可见性
    • 3.4 模块的多种定义方式
      • 3.4.1 内联模块
      • 3.4.2 文件模块
      • 3.4.3 目录模块
      • 3.5 模块路径与use关键字
        • 3.5.1 绝对路径与相对路径
        • 3.5.2 use关键字
        • 3.6 重导出
        • 3.7 访问控制与可见性
          • 3.7.1 可见性修饰符
          • 3.7.2 结构体与枚举的可见性
          • 3.7.3 通过super访问父级模块
          • 4、第三方库管理

            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();
            }
            

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

            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");
            }
            

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

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

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

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

            方式二:添加库

            我们在cargo创建的项目目录下,通过cargo new --lib mylib 创建一个库

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

            我们创建的库里面的lib.rs文件中有测试模块

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

            在我们创建的库mylib的src下创建个文件模块factory.rs,将之前通过内联模式创建的模块代码拿过来

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

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

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

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

            然后,在我们得项目的Cargo.toml文件中,将我们创建的库的路径指定

            在[dependencies]下面添加

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

            main.rs中导入我们创建的库,并使用

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

            3.4.3 目录模块

            对于更复杂的模块,可以使用目录形式。例如,创建一个client模块:

            src/

            ├── client/

            │ ├── mod.rs

            │ ├── http.rs

            │ └── tcp.rs

            ├── main.rs

            http.rs

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

            tcp.rs

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

            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();
            }
            

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

            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;
            

            起别名

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

            高级用法:

            // 嵌套路径
            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();
            }
            

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

            公有字段可以访问,私有字段不能访问

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

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

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

            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

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

            4、第三方库管理

            上面都是我们自己写的库,如果我们使用别人写好的库该怎么使用呢?比如加密库等

            Rust语言的库的官方网站crate,可以登录这个网站查找你想要的第三方库

            https://crates.io/

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

            需要修改Cargo.toml文件,来实现加载第三方库

            比如我们需要rand库

            直接搜索

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

            直接复制这个版本到Cargo.toml文件的dependencies下面

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

            放到dependencies下面,保存后就会自动加载依赖

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

            但是不推荐直接这种方式安装第三方库

            我们使用cargo-edit这个插件

            安装

            cargo install cargo-edit   
            

            添加库

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

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

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

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

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

            设置国内源

            推荐使用https://rsproxy.cn/。这个库比较全,速度也比较快

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

            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模块管理】Rust包、crate与模块管理

            第三方库使用案例:

            我们使用加密库rust-crypto

            先登录 https://crate.io

            查找该库

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

            通过cargo add来安装

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

            cargo add rust-crypto

            安装完之后,会在Cargo.toml文件中的dependencies中自动生成依赖和版本。我们就可以使用了

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

            使用第三方库

            //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);
            }
            

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

            edition 2018以及之后的版本用法

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

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码