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]

参考

相关推荐
SomeB1oody1 天前
【Rust自学】4.1. 所有权:栈内存 vs. 堆内存
开发语言·后端·rust
SomeB1oody2 天前
【Rust自学】4.2. 所有权规则、内存与分配
开发语言·后端·rust
SomeB1oody2 天前
【Rust自学】4.5. 切片(Slice)
开发语言·后端·rust
编码浪子2 天前
构建一个rust生产应用读书笔记6-拒绝无效订阅者02
开发语言·后端·rust
baiyu332 天前
1小时放弃Rust(1): Hello-World
rust
baiyu332 天前
1小时放弃Rust(2): 两数之和
rust
Source.Liu2 天前
数据特性库 前言
rust·cad·num-traits
编码浪子2 天前
构建一个rust生产应用读书笔记7-确认邮件1
数据库·rust·php
SomeB1oody2 天前
【Rust自学】3.6. 控制流:循环
开发语言·后端·rust
Andrew_Ryan2 天前
深入了解 Rust 核心开发团队:这些人如何塑造了世界上最安全的编程语言
rust