Rust项目结构

文章目录

一、module模块

crate规则:

  • 规则一:一个包中必须至少包含一个crate
  • 规则二:一个包中可以不包含库crate或者包含1个库crate
    规则三:一个包中可以包含任意数量的二进制crate

1.二进制文件的cargo项目

bin下面一个rs文件就是一个crate

2.库的cargo项目

模块中使用crate关键字

rust 复制代码
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // 绝对路径
    // 使用crate的原因是:
    // crate 的被称为 模块树 的模块结构的根部:https://rustwiki.org/zh-CN/book/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html
    crate::front_of_house::hosting::add_to_waitlist();

    // 相对路径
    front_of_house::hosting::add_to_waitlist();
}

模块中使用super

rust 复制代码
fn serve_order() {}

mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        // 访问父模块的函数
        super::serve_order();
    }

    fn cook_order() {}
}

模块中结构体的访问规则

rust 复制代码
mod back_of_house {
    pub struct Breakfast {
        //结构体成员默认是私有的
        pub toast: String,
        pub seasonal_fruit: String,
    }

    impl Breakfast {
        pub fn summer(toast: &str) -> Breakfast {
            Breakfast {
                toast: String::from(toast),
                seasonal_fruit: String::from("peaches"),
            }
        }
    }
}

pub fn eat_at_restaurant() {
    // 在夏天点一份黑麦面包作为早餐
    let mut meal = back_of_house::Breakfast::summer("Rye");
    // 更改我们想要的面包
    meal.toast = String::from("Wheat");
    println!("I'd like {} toast please", meal.toast);

    meal.seasonal_fruit = String::from("blueberries");

    let meal2 = back_of_house::Breakfast {
        toast: String::from("Wheat"),
        seasonal_fruit: String::from("strawberries"),
    };
}

模块中枚举的访问规则

rust 复制代码
mod back_of_house {
    // 枚举前面加上pub即可
    pub enum Appetizer {
        Soup,
        Salad,
    }
}

pub fn eat_at_restaurant() {
    let order1 = back_of_house::Appetizer::Soup;
    let order2 = back_of_house::Appetizer::Salad;
}

模块中use关键字

use关键字将路径引入到作用域中

rust 复制代码
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

//在一个模块里面,也可以直接使用self,use self::front_of_house::hosting;
// 函数:use引用其父亲模块,对于struct和enum则建议全部引入进来
use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}
fn main() {}

不同模块定义了相同类型冲突解决办法

rust 复制代码
// 引入父模块
use std::fmt;
use std::io;

fn function1() -> fmt::Result {
    // --snip--
}

fn function2() -> io::Result<()> {
    // --snip--
}
rust 复制代码
// 通过重命名解决
#![allow(unused)]
fn main() {
use std::fmt::Result;
use std::io::Result as IoResult;

fn function1() -> Result {
    // --snip--
    Ok(())
}

fn function2() -> IoResult<()> {
    // --snip--
    Ok(())
}
}

使用pub use导出本模块的函数给外面模块

rust 复制代码
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

pub use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}
fn main() {}

引入外部依赖

使用外部依赖

rust 复制代码
use rand::Rng;

fn main() {
    let secret_number = rand::thread_rng().gen_range(1..101);
}

模块与子模块

将front_of_house.rs中的子模块hosting定义在另外一个文件中,先创建front_of_house子目录,然后创建hosting.rs文件

模块是可以定义在同级的另外一个文件中的,如上所示,librs的mod front_of_house;

子模块是定义在以父模块为名的目录中的,如上所示,可以在front_of_house.rs模块中使用其子模块hosting.rs。

小结

1。Rust的模块系统概念包括:包package,包装箱crate,模块module和路径path。模块系统的目标是有效组织目录。

2。crate是Rust中的一个编译单元,它可以是一个二机制crate,也可以是一个库crate

3。cargo new缺省创建的是二进制项目,可以通过--bin指定创建二进制项目,或者--Lib~指定创建库项目

4。一个包package可以由一个或者多个crate组成。它包含一个Cargo。toml文件,其中可以定义它所包含的crates

5。一个包最多只能有一个库crate ,可以有任意多个二进制crate。但是一个包中必须至少有一个crate。

6。模块类似名字空间,可以逻辑拆分和组织代码。模块用关键字mod定义,模块可以是public也可以是private的。

7。缺省情况下,模块是private私有的,可以添加pub关键字,将一个模块设置为public的。模块中可以嵌套子模块。

8。路径path用于访问一个模块中定义的项。路径可以是相对的,也可以是绝对的。

3.文件内的module

关键字:mod

引入模块中的方法

  • usemod名字:方法名
  • usemod名字.*
  • 写全路径

二、模块化项目结构

·好处

  • 使源代码管理更加方便
  • 更方便读

1.关于module

默认是private

组成一个module

2.各个模块之间互相引用

crate根目录引入

super相对路径引入

三、推荐项目结构

bin目录

  • 把main.rs放入

somelib

  • 需要修改Cargo.toml
rust 复制代码
[somelib]
name ="somelib"
path="src/somelib/mod.rs"I  //文件夹
path="src/somelib/some.rs" //单个文件

1.实例

创建一个项目

创建一个库mlib

  • 创建单文件translate模块
  • 创建music目录模块
    mp3
    flac
    在flac调用translate模块中的方法
    将flac中的music方法暴露出去

main.rs

rust 复制代码
fn main() {
    println!("Hello, world!");

    mlib::translate::func1();

    mlib::music::flac::flac();
    mlib::music::flac::flac_music();

    mlib::test();
    mlib::flac_music();
}

src/mlib/music/flac.rs

rust 复制代码
pub fn flac() {
    //方法1 调用外层translate.rs里面的方法
    super::super::translate::func1();

    println!("flac");
}

pub fn flac_music() {
    // 方法2
    crate::translate::func1();
    println!("flac_music");
}

src/mlib/music/mod.rs

rust 复制代码
// 声明出去

pub mod flac;
pub mod mp3;

src/mlib/music/mp3.rs

rust 复制代码
pub fn mp3() {
    println!("mp3");
}

src/mlib/mod.rs

rust 复制代码
// 暴露模块
pub mod music;
pub mod translate;

pub fn test() {
    println!("test....");
}

// 暴露模块中的某个函数
pub use music::flac::flac_music;

src/mlib/translate.rs

rust 复制代码
pub fn func1() {
    println!("Hello,  func1!");
}

Cargo.toml

rust 复制代码
[package]
name = "demo"
version = "0.1.0"
edition = "2021"


[lib]
name="mlib"
path="src/mlib/mod.rs"


[dependencies]

参考

相关推荐
盒马盒马4 小时前
Rust:变量、常量与数据类型
开发语言·rust
傻啦嘿哟4 小时前
Rust爬虫实战:用reqwest+select打造高效网页抓取工具
开发语言·爬虫·rust
咸甜适中17 小时前
rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(十四)垂直滚动条
笔记·学习·rust·egui
张志鹏PHP全栈21 小时前
Rust第四天,Rust中常见编程概念
后端·rust
咸甜适中1 天前
rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(十五)网格布局
笔记·学习·rust·egui
susnm2 天前
最后的最后
rust·全栈
bruce541103 天前
深入理解 Rust Axum:两种依赖注入模式的实践与对比(二)
rust
该用户已不存在4 天前
这几款Rust工具,开发体验直线上升
前端·后端·rust
m0_480502646 天前
Rust 入门 生命周期-next2 (十九)
开发语言·后端·rust
寻月隐君6 天前
Rust Web 开发实战:使用 SQLx 连接 PostgreSQL 数据库
后端·rust·github